Inspiration

Every exchange — stocks, prediction markets, ticketing — is really one hard problem wearing a trench coat: a correct, always-on, globally consistent ledger. Traditionally that means a clearinghouse to guarantee trades, a distributed ledger to record them, and an infra team to keep balances consistent across regions through replication, failover, and overnight reconciliation. Three hard problems before you match a single order.

We kept staring at Amazon Aurora DSQL's pitch — strong consistency, optimistic concurrency, serverless, multi-region active-active — and realized it collapses all three into one primitive. So we asked: could one developer build a real, globally-fair exchange in a weekend, where orders match and money settles in the same transaction, with zero ops? Parity is the answer.

What it does

Parity is a real-time event exchange for binary YES/NO markets, with a central limit order book per market.

  • Trade live — place limit orders; they match with price-time priority against a live order book and settle instantly.
  • One-transaction settlement — a fill debits the buyer, credits the seller, updates both positions, appends ledger entries, and prints the trade — atomically.
  • Resolve a market — every winning contract pays 100¢, losers 0¢, in one consistent transaction set. No overnight reconciliation.
  • Portfolio — balance, positions, open orders, cancels — all live.
  • Prove it yourself — every fill is a balanced double-entry, so the ledger must net to zero. Hit /api/proof and the invariants are computed straight from the cluster, live.

Try it free with one click ("Enter as guest" mints a funded account) — no signup required.

How we built it

Aurora DSQL is the primary backend and the settlement ledger. The whole architecture is designed with DSQL's grain, which is what turns it from a naïve port into a showcase:

  • Matching is scoped per-market. Each market is its own contention domain — unrelated markets never conflict.
  • Every fill is a double-entry across distinct rows — debit one account, credit another, update two positions. Distinct rows are DSQL's optimistic-concurrency sweet spot, so independent trades commit in parallel without contending.
  • Conflicts retry, lock-free. On SQLSTATE 40001 (serialization failure) the whole short transaction retries with exponential backoff + jitter.
  • No negative balance, no double-spend — atomically. The debit is conditional: UPDATE accounts SET balance = balance - cost WHERE balance >= cost. If it can't fund, the fill simply doesn't happen. The invariant is enforced by the database, not by hope.
  • DSQL-aware schema: UUID primary keys (no sequences), no foreign keys (relationships enforced in app logic), and CREATE INDEX ASYNC — all applied and verified on the live cluster.
  • No hardcoded secrets. The Postgres password is a short-lived IAM auth token minted on demand by the AWS SDK signer.

The frontend is Next.js (App Router) on Vercel — a cinematic landing (React Three Fiber globe, scroll-driven architecture diagram, a live consistency readout), and the exchange itself: markets, a live trading page (order book, depth, ticket, trade tape), portfolio, and settlement. The realtime layer is deliberately boring and bulletproof: read-only polling of a conflict-free read path.

Proving it — strong consistency under contention, not eventual

We wrote a stress test that fires 200+ concurrent, conflicting trades across markets at once, then checks the books. On the real Aurora DSQL cluster:

  • Ledger imbalance: 0 — every debit found its credit
  • Negative balances: 0 — the conditional debit held under race
  • Cash conserved — total cash equals total deposits, exactly

/api/proof exposes those same invariants live, so a judge can verify them against the cluster in their own browser. This is DSQL strong consistency under contention — not eventual.

Testing note to add: "No signup needed — open the app, go to Markets, click Enter as guest for an instantly-funded account, then place a Buy YES order to see it match live."

What we learned

  • Designing with OCC is the whole game. The same workload is DSQL's best case (distinct rows) or worst case (one hot counter) depending entirely on schema design. An exchange is a perfect stress test of that distinction.
  • You can enforce financial invariants in the database itself — a conditional debit makes "no double-spend" a property of the system, not a code review.
  • DSQL being Postgres-compatible is a superpower — we built a dual-mode data layer so the identical app runs on local Postgres and on Aurora DSQL with a one-line env change.

Challenges we ran into

  • Modeling the match as one short transaction that stays in the OCC sweet spot while still doing buyer/seller/position/ledger writes correctly — and retrying the whole block on conflict.
  • DSQL isn't full Postgres: no sequences, no foreign keys, async index creation. We embraced those constraints in the schema instead of fighting them.
  • Keeping realtime trustworthy on camera — we chose polling over WebSockets so the demo never breaks.

What's next

  • Active-active multi-region. We run single-region today; because every write targets distinct rows under OCC, extending to DSQL's same-continent active-active (Tokyo + Seoul) is a configuration change, not a re-architecture.
  • A single-writer matching sequencer per market (LMAX-style) persisting fills to DSQL, for higher throughput.
  • An AI market-maker (Vercel Cron) to generate markets and seed liquidity.

Built With

Share this project:

Updates

Submission history