Synod Become a design partner

Multi-writer PostgreSQL on shared storage

Every server writes. Lose one, keep every commit.

Synod runs up to eight PostgreSQL writers on the same tables and one shared copy of the data, the way Oracle RAC does. When a writer fails, the others lock it out and carry on without any central coordinator. No acknowledged transaction is lost, and none is written twice.

Built from Neon's open-source storage, which we maintain in our own repository. Synod adds the multi-writer engine, the writers' own cluster membership, storage that splits into shards and fails over to a standby, and the installer and control plane that run it on your servers.

Writer 3 frozen for 45 s3 writers, 8 AWS machines
  1. writer 3 stops responding. Writers 1 and 2 keep committing. The control plane is switched off for the whole test.
  2. writer 1 has had no heartbeat answer for 30 s. It holds a majority with writer 2, so it locks writer 3 out of the log servers.writer 3 evicted by writer 1 in 0.03 s (no coordinator)
  3. writer 3 wakes up alone and may not evict anyone.this side has 1 of the 3 members
  4. writer 3 finds itself fenced and shuts down. Its host restarts it.this primary is fenced: safekeeper ... is in term 4, after our last elected term 3
  5. writer 3 rejoins, and the others hand back the pages it manages.writer 3 rejoins ... after 18.6 s evicted

No split brain. 31,063 changes acknowledged, 0 missing, the same rows on all three writers.

The evidence so far

0

acknowledged changes missing out of 309,727, across nine writer failures

AWS, 3 writers, Oct 28
30/30

random faults with every check consistent, 8 of them with a second fault at once

AWS, 60 minutes, Oct 30
541

tables identical on all three writers after PostgreSQL's own regression suite

3 writers, Oct 30
12.3s

for every writer to move to a standby page server after one was killed under load, with 0 errors and nothing lost

AWS, 3 page servers, Oct 31

Prototype software, tested in October 2026 on small machines. The full results and how we test are on the Results and Testing tabs.

The gap

PostgreSQL has no open-source answer to Oracle RAC

One writer at a time

A PostgreSQL cluster has one server that can write. Each replica keeps its own full copy of the data, and promoting one when the writer dies is left to outside tools.

Failover is where data goes missing

If the old writer is only unreachable rather than dead, it can keep accepting writes nobody will ever see. Preventing that split brain is the hardest part of any failover design.

RAC users have nowhere to go

Teams that run Oracle RAC for several writers on shared storage have no like-for-like open-source PostgreSQL option to move to.

Who it's for

Built for teams that can't lose a commit

Running Oracle RAC, or PostgreSQL you can't afford to lose?

We're looking for a few design partners for a free pilot on a non-production copy, with direct support from the team that built it.

Become a design partner

Technology

Writers share every table and coordinate among themselves

Database servers hold no data of their own. Every writer's changes go to three log servers and count once two of them have them on disk, and page servers rebuild any page on request, each with a standby that takes over if it fails. What Synod adds sits between the writers.

Three mechanisms, borrowed from RAC and rebuilt for PostgreSQL

  • Pages move between writers

    Each page has a managing writer, picked by hashing. A writer that needs to change a page asks that writer for the right to, and gets the current copy straight from whoever holds it, the way RAC's cache fusion works.

  • One commit order, no central clock

    Each writer numbers its own commits on a clock the writers keep in step. Every other writer hears of a commit before the client is told it succeeded. Old row versions live in an undo log, so readers never wait for writers.

  • The writers police each other

    Writers check on each other over the network and through the log servers. A majority locks out a silent writer by starting a new term on its log, so it can never commit again. When it comes back it rejoins on its own.

Applications one connection string naming every writer · TLS to any writer, no proxy WRITERS, ONE PER HOST, UP TO 8 (NO DATA OF THEIR OWN) Writer 1 Postgres + Synod Writer 2 Postgres + Synod Writer 3 Postgres + Synod Interconnect: the writers talk directly pages, lock waits, every commit, heartbeats, evictions SHARED STORAGE (NEON) 3 log servers, 2 agree Page servers Object storage (S3) Control plane creates clusters, moves a writer off a dead host off the commit path
Solid lines carry every query and commit. Dashed lines are management only: commits, evictions and restarts go on while the control plane is down.

What's Neon's, what's ours

Built on Neon's storage, extended to many writers on the same tables

From Neon's open-source storage

Apache 2.0, owned by Databricks

  • Shared storage: log servers, page servers and S3
  • A storage controller that can split a database into shards and keep standby copies
  • A new writer starts without copying the database
  • Election terms on each writer's log, which lock out an old writer
  • One writer per database

What Synod adds

Our own work

  • Up to eight writers on the same tables. A table engine with an undo log, page transfers between writers, one commit order across them, and row locks and deadlock detection that span writers. Tested with three writers on separate AWS machines.
  • Membership without a coordinator. Heartbeats over the network and through storage, majority rule for evictions, fencing through storage terms, and restart and rejoin without outside help.
  • Schema changes on every writer at once. ALTER TABLE, CREATE INDEX and table rewrites such as CLUSTER and VACUUM FULL commit on all writers together, while every writer keeps changing the table.
  • Direct, encrypted connections. Clients list every writer in one connection string, as RAC clients do. Each writer has its own TLS certificate and checks passwords itself; a password change reaches every writer together.
  • Backups and restores for the whole cluster. pg_dump from any writer gives one consistent snapshot. A restore point every minute, where no commit crosses between writers, lets a whole cluster be restored to that moment in seconds.
  • An installer and control plane for your own servers. Neon's own control plane is not open source. Ours sets up a cluster on separate machines, splits it into writers and moves a writer off a dead host.
  • Storage that scales out under every writer. With two or more page servers each database gets a standby, and every writer follows a move to it. A database splits into shards and a balancer spreads them across page servers while it runs. The map of page versions grows with the data. Tested on AWS with three page servers.
  • The test harness. Ledger checks across crashes and network splits, an isolation checker, randomized fault runs, and a replay for every bug found.

Deployment

Runs on your servers, in your data center or cloud account

One inventory file

List the machines and their roles. The installer sets up the log servers, page server, writers and control plane over SSH, as system services.

No single point of control

The control plane runs with a standby that takes over in about 3 s, and the writers keep committing while it is down.

Tested on AWS

Installed on 8 machines and checked through a control plane failover, a writer kill, a machine reboot and a full stop and start, with nothing lost. Ubuntu 24.04 today.

Synod RAC vs PostgreSQL, October 31, 2026

To your application, every writer is a PostgreSQL 17 server

Applications connect to any writer and read and write the same tables, in any database of the cluster. Ordinary SQL, transactions, backups, restores and failover behave as they do on one PostgreSQL server. Two features are refused, a few behave differently, and Synod is still a prototype.

Works like PostgreSQL

  • SQL and transactions

    Queries, joins, constraints, foreign keys, triggers, sequences, partitions, MERGE, ON CONFLICT; READ COMMITTED and REPEATABLE READ. SERIALIZABLE works too, differently (below).

  • Indexes

    B-tree, GIN, BRIN, GiST, SP-GiST and hash. CREATE INDEX, REINDEX and DROP INDEX, also CONCURRENTLY.

  • Schema changes

    Sent to any writer and made on every writer, while all of them keep working, even while one writer is down.

  • Databases and tablespaces

    CREATE and DROP DATABASE on any writer; every writer serves every database. Tablespaces and SET TABLESPACE.

  • Maintenance

    VACUUM, VACUUM FULL, CLUSTER and REINDEX, of one table, partitioned tables, a schema or the whole database.

  • Large rows

    Rows up to a page (about 8 KB) stored whole; larger values compressed or moved out of line, as in PostgreSQL.

  • Cluster-wide features

    Advisory locks, LOCK TABLE, LISTEN and NOTIFY and prepared transactions work across all the writers; so does subscribing to another database.

  • Backups and restores

    pg_dump, parallel too, and pg_restore. One database restored to any moment; a whole cluster to a restore point, one a minute.

  • Crash safety

    No acknowledged commit lost when one writer, or every writer at the same instant, is killed under load.

541 tables

PostgreSQL's own regression suite run on a three-writer cluster: afterwards every table is identical on all three writers and 424 B-tree indexes pass a full check against their tables. 62 of its 225 tests print something different from one PostgreSQL server: plans and row order, message wording, and the differences below.

Works, but differently

AreaOne PostgreSQL serverSynod RAC
A server failsClients wait for failover to a replicaThe other writers pause up to about 30 s, then carry on; the failed writer restarts and rejoins by itself
Writes to the same rows from several writersLocalA network round trip when another writer changed the data last
SERIALIZABLESerializable snapshot isolationStrict locking: also serializable, with more waiting, and a different transaction may be the one that fails
Shared row locks (FOR SHARE, some foreign-key checks)Several transactions share the lockSome wait for each other: slower, not wrong
Statistics views, temporary and unlogged tablesOne serverKept per writer
SET LOGGED / SET UNLOGGEDThe table keeps its rowsAn unlogged table is each writer's own copy; SET LOGGED keeps the rows of the writer that runs it
Prepared transactionsAlways allowedRefused if the transaction holds advisory locks, LOCK TABLE or SERIALIZABLE locks, or made a schema change
Cancelling a COMMITPossibleWaits until storage confirms the commit
Publishing changes (logical replication, CDC)Subscribers connect to the serverSubscribers connect to synod_cdc, a small server in front of the cluster that sends every writer's changes in commit order
CREATE / DROP DATABASEAny time, from any templateMade or dropped on every writer at once; every writer must be up; template0 or template1; up to 16 databases
Tablespace locationFiles go in that directoryAccepted but not used: the data stays in the cluster's shared storage
GIN fastupdateNew entries wait in a pending listAccepted; entries go straight into the index (same results, inserts a little slower)

Refused, with a clear message

  • Switching a table to another storage format (SET ACCESS METHOD): shared tables use Synod's own format.
  • Renaming a database, or making one from a template other than template0 or template1.

Limits today

  • A prototype. Tested with up to three writers (eight allowed), on small machines in one AWS zone, in runs of up to 90 minutes. No production use yet.
  • A failed writer pauses the others. Commits on the other writers wait up to about 30 s (a setting), until it is evicted.
  • Page servers. With two or more, every database has a standby; when a page server fails, its work moves to the standby in about 12 s, and reads that need it wait until then. Tested with three page servers and a few GB, not yet at multi-terabyte sizes.
  • Cold scans. Reading a whole shared table that is not in memory runs at about 200 pages a second per writer on small machines, until read-ahead is built.
  • A private network. Traffic between the writers is not encrypted yet, and storage trusts its network.
  • Upgrades. All writers are upgraded together; no rolling upgrades yet.

Several databases per cluster, SET LOGGED / UNLOGGED, rows up to a page, publishing changes through synod_cdc, and the maintenance statements once refused were added on October 30 and are in the installer since October 31; the AWS suite passed on that build. The features themselves are tested on a local three-writer cluster.

AWS results, October 28–31, 2026

Kill a writer or a page server: the ledger stays exact

Three writers on three machines, three log servers, one to three page servers and S3: 8 AWS machines with 2 vCPUs and 8 GB each. Clients on every writer insert, delete and re-key rows of shared tables. After each failure, every acknowledged change must be there, the rows must be the same on every writer, and every index must match its table.

Storage scale-out, October 31, 2026

Split the storage, kill a page server, add one: nothing lost

Three writers on separate machines changed shared tables, about 174 times a second each, in a 1 GB database of 900,000 rows, while we split its storage, killed a page server and added a new one. Disks and the bucket were encrypted with AWS KMS.

1.8s

to split the running database into 4 shards; every writer was reading the new shards 5.2 s after the request

12.3s

from killing the page server that held shard 0 until every writer read it from the standby, which took over after 10.1 s

0

errors in the load, committed changes missing and lost updates; the data identical on all three writers and every index checked clean

StepWhat happenedTime
Split into 4 shardsUnder loadThe database split on page server B, and every writer switched to the new shards.1.8 swriters 5.2 s
Shards spreadBy the balancerShard 0 moved to page server A; every shard kept a standby copy on the other server.16 s
Page server killedkill -9, kept downThe standby on B took over shard 0. Reads that needed it waited meanwhile, and the load saw no errors.10.1 swriters 12.3 s
Killed page server restartedIt came back as a standby.—
Third page server addedWhile the load ranThe balancer moved shard 0 to it, and the writers followed.82 s
Silent, with captions, 2 minutes 20 seconds. A replay of the AWS runs of October 30–31, 2026 on 8 machines: first nine writer faults, then the storage steps. Every number on screen is from the runs; long waits are sped up and marked.

The first storage run on AWS found that writers restarted earlier in the test did not follow storage moves. That is fixed, and the results above are from the rerun on a fresh cluster.

Writer failures, October 28, 2026

0

acknowledged changes missing out of 309,727, across nine writer failures with the control plane switched off

0.03s

for the remaining writers to lock out a silent one, once its 30 s heartbeat timeout ran out

7.5–21s

for an evicted writer to come back, rejoin and take back the pages it manages, with no operator involved

Every failure, and what the ledger showed

FailureWhat happenedAcknowledgedMissing
Writer killedEach of the three in turnIts host restarted it in place. The other writers forgot what it held and kept going.138,7050
Writer frozen for 45 sEach of the three in turnEvicted after the 30 s heartbeat timeout and locked out of storage. On waking it found itself fenced, restarted and rejoined 17–19 s after its eviction.89,4360
Network splitOne writer cut off from the other twoThe majority evicted it. It rejoined about 20 s later, once the network healed.55,5120
Page transfer service frozen for 45 sPostgres still upEvicted like a frozen writer. Rejoined 7.5 s after its eviction.26,0740
Six table rewrites under loadALTER COLUMN TYPE, CLUSTER, VACUUM FULLEach took 2–28 s and ran on all three writers together while every writer kept changing the table.8,8470
Schema changes from every writerUnder loadSystem catalogs identical on all three writers afterwards. Index cleanup: 139,161 rows and 139,161 index entries on each writer, every index verified.—0

The heartbeat timeout is a setting (30 s by default). A writer that is killed rather than frozen is restarted in place without waiting for it: its host notices the exit and the other writers drop what the old run held.

Rerun on October 30 on the finished engine, installed with our installer on 8 AWS machines: 18 of 18 three-writer tests passed, with every acknowledged change present. Run again on October 30–31 with three page servers: the nine writer faults, schema changes under load, index checks and table rewrites all passed, with no committed change missing.

Watch the three-writer tests

A freeze, a kill, a network split and six table rewrites, in two minutes

Silent, with captions. Recorded on 8 AWS machines on October 28, 2026, with the control plane switched off: the writers' counts and log lines are the test's own; long waits are sped up and marked on screen. Ends with the October 29 randomized fault runs.

Earlier: one writer per database (stages 1 and 2, October 25)

FailureWhat happenedAcknowledgedIn the ledger
Writer cut off from storageClients can still reach itReplacement writing after 4.4 s. The old writer committed nothing and was refused when the network healed.65,49465,502+8 in flight
2 of 3 log servers stopThen restartWrites pause with no errors and resume about 5 s after the servers return.148,512148,512
Page server stops for 20 sNo drop in throughput.154,802154,802
Database moved to another serverPlanned, under loadWriting on the new server after 16.3 s with default storage settings, 1.3 s with storage tuned for fast starts.22,36322,363

A bank workload: each transaction moves money between two accounts and writes a ledger row. "In flight" commits were running when a server died, so the client never got an answer; they may be in the ledger, and acknowledged commits always are.

Speed

2,649 TPS

One writer, 16 clients over the network: 43% of plain PostgreSQL 17 on the same machine type, with every commit stored on two other machines before it is acknowledged.

~4,240 TPS

Four databases with writers on two machines, sharing one storage service. A second writer machine adds throughput.

3,535 TPS

Two writers in one database, each owning its own tables and reading the other's: our first multi-writer prototype.

Next

Throughput with every writer changing the same tables has not been tuned yet. That is the next piece of work.

How we test it, October 31, 2026

We try to break it on purpose, then replay every break

A multi-writer database fails in rare timings that ordinary tests never hit. So we run eight kinds of test against three-writer clusters, and every bug they find becomes a replay that forces that exact timing.

PostgreSQL's own test suites

The regression and isolation suites run against a three-writer cluster. Afterwards all 541 tables are identical on the three writers and 424 B-tree indexes pass a full check against their tables.

62 of 225 regression tests print something different: plans, row order, wording and the differences on the vs PostgreSQL tab

Isolation under faults

Clients on every writer append to lists and read them back at REPEATABLE READ while writers are killed, frozen or cut off. Each history is checked for dirty or lost writes and for lost or diverging appends.

Only write skew found, which REPEATABLE READ allows

Randomized fault runs

Runs of 40 to 80 minutes that pick a failure at random, sometimes two at once: a writer killed, frozen or cut off, its page transfer service stopped or frozen, a log server or the page server killed. Under load, on one machine and on 8 AWS machines.

AWS, October 30, finished engine: 30 random faults in 60 minutes, 8 of them with a second fault at once, 30 of 30 consistent. Earlier, a 36th fault exposed the stale index entry below

A replay for every bug

Each bug is made to happen on purpose with test pause points. A fix counts only when the replay keeps the data and a build without the fix loses it.

12 replays; each fix, built without it, fails its replay

Every writer killed at once

All three writers killed in the same instant, three times, while clients move money between accounts: the power failure of a whole cluster.

Nothing acknowledged missing, no lost update, 3 of 3

Backups and restores

A dump from any writer under load is one consistent snapshot, and parallel dumps restore into one database or a new cluster. A whole cluster restored to a restore point has every transfer acknowledged before it, and none started after.

Cluster restored in 2.0 s; a restore point pauses commits for 0.1–0.4 s

Storage faults

A page server killed under the shared-table load, the database split into shards and moved between page servers, and a new page server added, while every writer keeps changing the same tables.

AWS, October 31: split in 1.8 s, writers on the standby 12.3 s after the kill, 0 errors, nothing missing

Page version map stress

Each writer keeps a map of page versions that grows with the data. Stress runs on a build with small buckets add 100,000 entries per writer, about 4,300 splits each, under load and with a writer killed.

6 of 6 stress checks and 10 of 10 map checks pass, including reads by another writer from storage

What the tests found, all fixed

  • After an eviction, a page's new managing writer could reuse a version number already given out, so a stale copy could later win.

    Fault test, one machine
  • A writer that restarted could carry out a page hand-off meant for its previous run, losing index entries.

    AWS fault test
  • A writer asked for a page it had just received could send an older copy while still adding rows to it.

    Randomized run
  • A writer reading a page back from storage could send the older copy while also changing it.

    AWS randomized run
  • A request carried out after its sender had given up could drop a page in the middle of a change.

    Code review
  • A writer killed while waiting for the log servers could still hand over a page whose changes were then lost, leaving an index entry for a row that never existed.

    AWS randomized run
  • A commit cancelled while it waited for the log servers became visible to the other writers before it was durable, so a crash could leave them keeping a change its own writer had lost.

    Code reading
  • A writer rejoining while another was growing a table could stall both until a timeout.

    Randomized run
  • AFTER UPDATE triggers and foreign-key checks saw the new row as the old one, so orphan rows were possible.

    Regression suite
  • An evicted writer could answer a query from stale data before it learned it was out. Writers now check they still hold a read lease before each snapshot.

    Fault test, one machine
  • New hash index pages skipped the step that tells the other writers who holds the latest copy, so pages could be lost.

    Feature test
  • An UPDATE that moved a row to another partition made a concurrent UPDATE or DELETE of that row silently do nothing.

    Isolation suite
  • An UPDATE or MERGE that waited for another transaction could write back a value that transaction rolled back.

    Isolation suite
  • A foreign-key check at REPEATABLE READ didn't fail after a concurrent change to the parent row, as PostgreSQL's does.

    Isolation suite
  • An ALTER TABLE ... TYPE that kept an index's file deleted that file on the other writers.

    Regression suite
  • Writers restarted in place did not follow the storage when it moved to another page server.

    AWS storage test
  • A split of the page version map could stall the service that hands pages between writers.

    Stress test
  • A management port that takes no password listened on every network interface instead of only on the machine itself.

    Code review

The most serious bugs found so far, all fixed. Since October 29 our tests and reviews have found more than 30 bugs in all, and every one is fixed.

Roadmap

Three stages, each a product on its own

Customers who need RAC's availability before its scale-out can start with the first two stages. The third, several writers on the same tables, is working on AWS with three writers.

  1. Stage 1

    One writer, many readers

    Automatic failover and read scale-out on shared storage.

    Tested on AWS

    Neon's storage handles the failover; our control plane automates it.

  2. Stage 2

    A writer per database

    Many databases on one storage service, each with its own writer, moved between servers without copying data.

    Tested on AWS

    Neon's storage supports it; our control plane places and moves the writers.

  3. Stage 3

    Writers share tables

    Several servers writing the same tables at once, the way Oracle RAC does.

    Working on AWS with 3 writers

    Our own work: up to eight writers on every table, membership without a coordinator, schema changes on all writers.

What production needs next

  • Throughput on shared tables. Speed when every writer changes the same tables has not been tuned yet.

    Next
  • Encrypted traffic between writers and between writers and storage, with the option of a customer's own KMS key.

    Next
  • Read-ahead for shared tables, so cold full scans are no longer limited to about 200 pages a second per writer.

    Next
  • Disaster recovery to another region. Built on October 30; the local test brought a cluster back in 10 s. The AWS rerun is still to do.

    In test
  • Multi-terabyte tests on bigger machines.

    Planned
  • Rolling upgrades, one writer at a time.

    Planned
  • Several page servers. A standby for every database with automatic failover, and shards spread across page servers while the database runs.

    Tested on AWS
  • October 30 features in the installer. Several databases per cluster, SET LOGGED / UNLOGGED, large rows and synod_cdc; the AWS suite passed on that build.

    Done

Funding and design partners

Help take Synod from tested prototype to production

We are raising to hire experienced database engineers and turn Synod into something teams can run in production: multi-writer clusters, failover, upgrades, backups and monitoring.

Design partners

We're looking for a few teams that run Oracle RAC today, or run PostgreSQL and can't afford a gap when a server fails. Migration firms with RAC databases their clients couldn't move are welcome too.

What a design partner gets

  • A free pilot on a non-production copy, installed with our installer and pilot operations guide
  • Direct engineering support from the team that built Synod
  • Founding-customer pricing when Synod goes to production

What we ask

  • An hour of feedback every two weeks during the pilot
  • A realistic workload, so the tests reflect what you run

Investors

We're raising a seed round. Write to us for the deck and a walkthrough of the fault tests.

Email

Open in mail

Tell us what you run today: the database, how many servers, and what a failure costs you.