# Project Orion: Galactus DB 2.0

Galactus DB 2.0 is the biggest change we have made to how your graph is
stored. We call it Orion. A database with two million nodes and four million
relationships now opens in **0.2 seconds instead of 17**, answers reads
**nearly three times as fast**, and does it in **a fifth of the memory**.
Your drivers, your Cypher and your node ids stay exactly as they are.

![Seconds to open a 2-million-node database, 1.8 against 2.0](/blog/charts/release-200-reopen.svg)

## Why we rebuilt it

Until now, Galactus DB kept the shape of your graph in RAM: every node, every
relationship, every index. That made it quick, and it meant your machine had
to be big enough for the whole graph. Opening a database meant reading the
whole history back into memory, so a bigger graph took longer to start every
time.

Orion keeps the graph on disk instead, in small checksummed pages, and keeps
the pages you are using in memory. Think of a library rather than a desk: the
books you are reading are open in front of you, the rest are on the shelves,
in order, a few steps away. Opening the library means unlocking the door;
nobody carries every book to your desk first.

## What you get

- **Every index on disk.** Range, hash, composite, unique constraints,
  full-text, vector, point and spatial indexes all live in pages beside the
  graph. Nothing is rebuilt when a database opens, however large it is.
- **One memory budget.** Set `GDB_MEMORY_LIMIT`, or let Galactus DB read the
  container's limit, and the page cache takes its share. Hot data, the
  topology and the upper levels of every index stay pinned in memory; the
  rest comes and goes as queries need it.
- **Graphs bigger than the machine.** The same 574 MB database served from a
  16 MiB cache still answers 25,000 reads a second, in 34 MB of memory.
- **Writes that never stop the world.** Changes are written to pages on a
  thread of their own while your readers and writers carry on.
- **Dumps of any size.** Dumps are no longer capped at 4 GiB, and restoring
  one streams it straight into pages: half the time of 1.8's restore, in a
  fifth of the memory.

![Memory for the same 2-million-node database, after opening and while answering reads](/blog/charts/release-200-memory.svg)

Reads get faster as well as cheaper. Most reads now come straight from pinned
pages, with no locks and no searching:

![Reads per second on the same database, 1.8 against 2.0](/blog/charts/release-200-reads.svg)

And with readers and writers working at once, the way the server runs them,
writers keep their pace and readers gain:

![Writes and reads per second with 8 writers and 8 readers](/blog/charts/release-200-together.svg)

## Bigger than its memory

We gave the 2-million-node database less and less memory to see what happens.
It keeps answering, every time, and slows gradually as the cache shrinks:

![Reads per second as the page cache shrinks from 1 GiB to 16 MiB](/blog/charts/release-200-cache.svg)

That is what lets you run Galactus DB beside your application on the server
you already have, a database per customer, or a large graph on a small cloud
instance.

## Upgrading: one setting

Pull 2.0 and start it on the same data volume with one extra setting:

```yaml
services:
  galactus-db:
    image: ianknowles/galactus-db:2.0.0
    environment:
      GDB_AUTO_UPGRADE: "true"
    volumes:
      - galactus-data:/data
```

On its first start, 2.0 takes a dump of each database into its `backup`
folder, then moves it onto Orion. A 2-million-node database moves in about a
minute; a small one in well under a second. Databases that are already on
Orion are left alone, so the setting can stay on. Our own compose files and
Docker examples now ship with it on.

Prefer to choose the moment? Leave the setting off and every database keeps
running exactly as it did on 1.8. Move each one when it suits you:

```cypher
ALTER DATABASE galactus SET ENGINE PAGED;
```

New databases are created on Orion from the start.

Everything is reversible. A dump from 2.0 restores on 1.8, and
`ALTER DATABASE … SET ENGINE HYBRID` moves a database back. You can see where
every database stands:

```cypher
SHOW DATABASES;
CALL gdb.storage();
```

`SHOW DATABASES` now reports each database's engine, storage format and the
release that last opened it, and `gdb.storage()` adds its size on disk and how
well the page cache is serving it. The [upgrade guide](/docs/operations/upgrade-2.0)
walks through every path.

## Built to be trusted

A storage engine has one job above all others: give back exactly what you
gave it. Before this release:

- every one of the 1,572 tests in our suite passed on Orion, on the 1.x
  engines, and with a page cache of just 1 MiB;
- we killed the server mid-write at random, over and over, and checked every
  acknowledged transaction was still there;
- we took databases and dumps written by Galactus DB 1.8, upgraded them with
  2.0, and checked every answer matched, query for query;
- every page carries a checksum, so a damaged page is caught, never served.

The 2.0 storage format is now frozen in our test suite: every future release
must open a database written by 2.0.0 and give the same answers. What comes
next is added beside it.

## How we measured

A release build of Galactus DB 1.8.0 and 2.0.0 ran natively on an Intel Core
i9-13900K with 64 GB of RAM and a Samsung 990 PRO NVMe drive, on Windows 11,
using our `gdb-bench` harness. The large database had 2,000,000 nodes and
4,000,000 relationships with a hash and a range index, loaded with buffered
durability; 1.8 used its Hybrid engine and 2.0 its default page cache. Reads
were an index lookup and a two-hop count from 4 readers for 8 seconds. The
mixed runs used 300,000 nodes with 8 writers and 8 readers, interleaving
1.8 and 2.0 over three rounds so the disk treated both alike. Peak memory is
the process's peak working set.

Loading a graph from scratch takes Orion longer than 1.8, because it writes
pages as it goes: 26.5 seconds against 19.6 for the 2-million-node load.
Databases that stay on the 1.x engines in 2.0 load and run exactly as they
did on 1.8.

## Get it

```text
docker pull ianknowles/galactus-db:2.0.0
```

Add `GDB_AUTO_UPGRADE: "true"`, start it, and your graph is on Orion.
