Inspiration

On August 1, 2012, Knight Capital deployed a software update that left dead code active on one of its eight servers. For 45 minutes, that server re-sent the same parent orders to the market over and over, executing millions of shares it was never supposed to. By the time it was halted, Knight had taken on billions in unintended positions and lost ~$440 million — roughly four times the company's prior-year profit. It was acquired within months. The firm was destroyed not by a market crash or a hack, but by a single order executing more than once, with no second line of defense.

That failure mode never went away — it is the permanent nightmare of every system that settles money. Exchanges, crypto venues, and prediction markets all live or die on one guarantee: one match, one settlement — never twice. We wanted to know if Amazon's newest distributed database, Aurora DSQL, could make that guarantee structural — enforced by the database itself rather than by hopeful application code — and whether it could deliver something legacy exchange architecture genuinely cannot: one strongly-consistent ledger of truth across multiple AWS Regions at once.

AXIOM is our answer: a self-contained exchange core — the matching engine, settlement ledger, and custody layer a new trading venue runs as its own backbone, instead of building one from scratch or licensing a legacy black box.

What it does

AXIOM accepts orders, matches them with continuous price-time priority, settles the resulting trades into an immutable ledger, and moves the underlying custody balances — all under two non-negotiable guarantees:

  1. Exactly-once execution. Under a storm of duplicate or retried orders, exactly one settles. We prove it: fire 50 identical submissions sharing one idempotency key → 1 accepted, 49 rejected by a database UNIQUE constraint (SQLSTATE 23505), 0 double-executions. This is the literal Knight Capital safeguard, enforced by the database.

  2. One ledger across Regions. A live two-Region active-active Aurora DSQL cluster (us-east-1 + us-east-2, witness us-west-2) presents a single logical, strongly-consistent database with two writable Regional endpoints. A trade written through one Region is instantly, durably readable from the other — no read replicas, no eventual consistency, no reconciliation job, RPO 0.

Beyond the headline guarantees, AXIOM implements real exchange semantics:

  • Order types / time-in-force: GTC, IOC, FOK, and POST_ONLY.
  • Self-trade prevention: orders carry an account_id; an account cannot fill against itself.
  • Atomic settlement & custody: when a fill occurs, the engine moves both sides' balances in the same transaction as the trade — buyer gains the base asset and is debited the quote notional; seller is the mirror. The four balance deltas sum to zero per asset, so value is conserved, never minted.
  • Fixed-point money math: all prices and quantities are NUMERIC(18,8) in the database and scaled bigint in the engine — there is no floating-point arithmetic anywhere on the value path, so a fill can never drift by a rounding error.

A live dashboard shows the order book, trade tape, settlement ledger, and a one-click "Knight Capital Mode" that fires the duplicate-order storm so judges can watch the database reject every duplicate in real time.

How we built it

The entire correctness claim rests on one rule, stated at the top of the matching engine: every trade-affecting write — the order, every fill, every balance move — happens inside a single optimistic-concurrency (OCC) transaction. There is no "fast path." Reintroducing one is the Knight Capital failure mode.

The matching transaction (TypeScript) is the sole writer of the trades ledger and account_balances. In one transaction it:

  1. Inserts the incoming order, reserving its idempotency_key — a UNIQUE violation here means a duplicate, returned as REJECTED_DUPLICATE (terminal, never retried).
  2. Reads crossing resting liquidity in price-time priority (best price first, then oldest first), bounded to 1,000 resting orders per match to stay safely under DSQL's 3,000-rows-per-transaction limit.
  3. Walks and fills, decrementing both sides with a status-guarded UPDATE, inserting one trade row per fill, and settling custody balances inline.
  4. Commits. If any contending transaction touched a row this one read or wrote, the commit fails and the whole body re-runs on a fresh snapshot.

Aurora DSQL runs every transaction at REPEATABLE READ and is lock-free — it never blocks on row locks; it validates at commit time. Two transactions touching the same order row cannot both win: the later committer is rejected with SQLSTATE 40001 and our retry runner transparently re-executes the entire transaction body against a new snapshot, with exponential backoff and full jitter (5 ms base, 250 ms ceiling, up to 100 attempts) to de-synchronize contenders. Because competing matchers always write the same resting rows, the conflict is a write-write conflict OCC always detects — so the book cannot be double-filled or driven negative.

Database-enforced invariants (not application promises):

  • UNIQUE(idempotency_key) — duplicates can't be inserted twice.
  • CHECK(remaining_quantity >= 0) — the order book can never go negative.
  • CHECK(balance >= 0) on account_balances — a settlement that would overdraw any account aborts the whole transaction, rolling back the trade that caused it. Custody can never go negative, and a trade and its settlement commit together or not at all.

Multi-Region is a per-Region connection layer that opens one IAM-authenticated pool per endpoint and routes writes by region. The matching engine code is unchanged — a cross-Region write-write conflict surfaces as the very same SQLSTATE 40001 and retries identically. Active-active correctness is a property of the database; our layer just opens the doors to both Regions.

DynamoDB is a fire-and-forget audit firehose (append-only order/trade/rejection events), deliberately kept off the settlement critical path so it can never add latency to — or fail — a trade. Aurora DSQL is the sole source of truth.

Stack: Next.js 15 dashboard on Vercel; Fastify intake API (region tagging, idempotency, read projections); a TypeScript monorepo. The concurrency proofs run against an embedded PostgreSQL with zero infrastructure (npm test) — because stock Postgres at REPEATABLE READ raises the identical SQLSTATE 40001, the local proof faithfully exercises the exact DSQL code path.

Proven, against live infrastructure

These are measured, reproducible results — every script is in the repo:

  • Concurrency: 50 conflicting BUY orders against 10 units of resting liquidity → exactly 10.0 executed, 0 negative quantities, every trade referencing real orders, and hundreds of real OCC retries forced by genuine contention.
  • Idempotency: 50 simultaneous submissions of one key → 1 accepted, 49 rejected, 1 row persisted, 0 trades.
  • Convergence (live multi-Region): a SELL written via the us-east-1 endpoint was matched by a BUY written via the us-east-2 endpoint; both endpoints then reported the identical ledger (trades=1, executed_qty=2.00000000, open_orders=0). One ledger, zero divergence.
  • Failover (live multi-Region): a trade was committed via one Region, that Region's connection was severed, and the surviving Region still held the committed trade with full fidelity (zero data loss, RPO 0) and accepted new writes — no reconciliation step.

Challenges we ran into

  • Aurora DSQL is not textbook Postgres. No SERIALIZABLE isolation, no SELECT … FOR UPDATE locking, no foreign keys, a 3,000-row transaction cap, and ALTER TABLE ADD COLUMN that rejects DEFAULT/NOT NULL/CHECK. We rebuilt correctness around DSQL's real model — REPEATABLE READ + OCC — and enforce referential integrity structurally: every trade and every balance move is written in the same transaction that reads and decrements the orders it references, so a trade can never reference a non-existent order, and balances can never drift from the trade ledger.

  • Evolving a live schema. Once a migration is applied to the live DSQL cluster it is immutable, and DSQL's ALTER restrictions meant we couldn't simply edit the original CREATE TABLE. Adding order types, self-trade prevention, and the custody ledger meant new, append-only migrations that add bare nullable columns, backfill them, and lean on the application's Zod validation — while a fresh database still gets the full constraints from the original CREATE TABLE.

  • Per-Region IAM auth. DSQL auth tokens are short-lived and Region-specific, so a long-running server can't mint one at startup and hold it. We generate a fresh token per connection (via the SDK's request signer) and bind each pool to its own Region's signer.

  • Honesty under pressure. We refused to publish numbers we hadn't measured. Our README explicitly separates capability from measured results, and we only reported multi-Region numbers after capturing them against a live cluster — which we then tore down to stop billing.

What we learned

The headline lesson: "uses Aurora DSQL" and "exploits what only Aurora DSQL can do" are different things. Single-Region Postgres can already do exactly-once matching. What it cannot do is be multi-Region active-active with synchronous strong consistency and zero RPO — and that is exactly where a globally-consistent settlement-and-custody ledger becomes possible without reconciliation. The durable value isn't the matching algorithm (those have existed for decades); it's the correctness architecture — exactly-once execution, atomic trade-plus-settlement, and database-enforced invariants — which is what would survive even if you swapped the database underneath it.

What's next

A FIX-protocol gateway (the production front door real trading firms speak), a third peered Region for a true three-continent active-active demo, and a deeper push into prediction-market settlement, where exactly-once resolution against an external oracle — paying out a market exactly once when it resolves — is precisely the hard problem AXIOM's transaction model is built to solve.

Built With

  • amazon-aurora-dsql
  • amazon-dynamodb
  • aws-sdk-for-javascript-(dsql-signer)
  • embedded-postgres
  • fastify
  • iam
  • next.js-15
  • node-postgres
  • node.js
  • postgresql-wire-protocol
  • react
  • tailwind-css
  • typescript
  • vercel
  • vitest
  • zod
Share this project:

Updates