How it works
One storage engine, built for branches
Stolon is its own storage engine, a fully persistent B-tree, behind the PostgreSQL wire protocol. It is not a Postgres fork.
The shape of it
- Clients speak the PostgreSQL wire protocol (psql, psycopg, node-postgres, SQLAlchemy, Alembic) or MCP. The database name in the connection string selects the branch.
- The SQL layer is judged against a live PostgreSQL on every test run: 210 script families, comparing rows, command tags and errors. Check your own queries.
- The engine keeps every committed state readable, and any of them can start a new branch. Schema changes branch and merge with the rows.
main.
Restore keeps the present as a branch first.Branches
A branch copies no rows and no pages, whatever the size of the data. A read
on a branch costs what a read on main costs, however deep the
branch sits and however many siblings it has.
More on fully persistent B-trees.
History
FOR SYSTEM_TIME AS OF reads any table as it was at a past
moment. COMPARE DATABASE shows what changed between two moments
and says its plan before it reads. History is kept for your plan's window.
Merge
MERGE DATABASE b INTO main is a three-way merge, decided column
by column, so a backfill on a branch and live traffic on main
compose. It is atomic: a conflict applies nothing and names the row and
column, and DRY RUN previews the whole result.
Durability
- A commit is acknowledged only once it is on disk, and every acknowledged write survives a SIGKILL.
- Every page is checksummed. A damaged page is never served.
- The log can be shipped to object storage as it is written. Restored from
the bucket alone after
kill -9with every local file deleted, a database lost no acknowledged write. - A read-only standby follows a database and can be promoted.
What has been measured
| Property | Result |
|---|---|
| Branch creation | 27.4 ns → 28.8 ns per branch from 1,000 to 100,000 branches (1.10x) |
| Depth | reads on a branch 125 levels deep cost what reads on main cost |
| Width | a read scans 2,100 entries and 16 pages at 100, 1,000 and 10,000 live branches |
| Crash recovery | 61 crash points: 30 roll back, 31 roll forward, 0 corrupt |
| Larger than memory | 5.3x memory on disk, reads flat across 100 levels of depth on a cold cache |
| Throughput | 5,648 durable writes/s and 11,504 reads/s at 64 connections |
| Idle | an idle, empty database is 3.23 MB of memory and 20 KB of disk |
| Against Doltgres | on an external benchmark's agent-exploration workload: 1.14x total time, 1.03x branch creation, 4.0x less storage on a deep branch spine |
A test in the repository reproduces each result.