Room 1 of 3

Ledger Under Fire

Fire twelve payments at one account at the same moment, on the unsafe path and then the safe one.

  1. Watch the balance come out wrong, then watch it come out right.
  2. Read which writes were refused and why.
What this shows
Keeping money correct when several things touch the same record at once.
How
  • Read-then-write race, two requests read the same balance before either one writes, so the second quietly overwrites the first.
  • Idempotency key, an id the caller sends and the database stores, so a retried payment lands once instead of twice.
  • Conditional update, one statement that refuses if the balance changed, so the rule holds inside the write rather than in a nightly repair job.
What this demo is and is not
What is realTwelve real HTTP requests, each a real database transaction.Cloudflare D1 serialises writes, so the race sits in the application code rather than the engine, the same as in production.
What is stagedThe company, the accounts and the amounts are invented.The unsafe path reads a balance, awaits, then writes the sum it computed, the shape this bug takes in real code.
What this does not proveNot that the safe path would hold at a real company's size.This is a dozen requests against a free database, not a payments system under load.

Twelve payments, one account, no waiting in line. What do the books say afterwards?

  • Every payment debits the same operating account and credits a vendor account.
  • Only the debit is raced.
  • Crediting is one atomic SQL increment in both modes, so the bug sits in the single read-then-write gap the unsafe path takes.