Ledger Rebuild

Drift to daily balance, in seventy seconds — watch, or read the same rebuild below

A fintech client’s transaction ledger had drifted from its bank balances, and no one could say by how much. I rebuilt it as an append-only double-entry core with automated reconciliation, migrated live data with parallel runs, and handed back books that balance daily.

Who this story is for

Any team whose payment code is guarded by one nervous engineer, whose finance calendar contains a recurring meeting about “the difference”, or whose auditor’s questions take days to answer. The details below are one client’s; the shape is an industry’s.

The situation

The client was growing faster than its first database schema — the most common origin story in fintech, and nothing to be ashamed of: the schema that ships the MVP is never the schema that survives scale. Balances were a column, updated in place. Corrections were UPDATEs, applied by whoever was on call. History was whatever the last write said it was.

The symptoms arrived in the usual order. First the small unexplained differences between the dashboard and the bank, absorbed as rounding. Then the month-end meeting that existed solely to negotiate which number was true. Then the moment that forces the phone call: a difference too large to absorb, too old to trace, and growing — with an audit on the calendar and a funding conversation behind it, because drifted books surface at exactly the moments they cost the most. By the time we spoke, the finance team was spending its best week every month on archaeology, and the engineering team was afraid to touch the payment code at all. Fear of your own ledger is the surest sign the architecture is done.

What I did

Weeks 1–2: forensic reconciliation. Before building anything, find the truth. I replayed the full transaction history into a shadow ledger — every payment, refund, fee and adjustment reposted as proper double-entry events — and reconciled the result against bank statements and gateway settlement files. The drift had causes; it always does: duplicate webhook processing without idempotency keys, refunds that bypassed the posting rules, and manual corrections that fixed screens while corrupting history. Each cause became a countable category with a rupee figure, which converted the fear into a work list.

Weeks 3–6: the new core. The architecture this site teaches, built for real: immutable events as the only way money enters the record; double-entry postings enforced at the write, so imbalance is structurally unrepresentable; balances as projections, cached for speed and rebuildable from scratch; idempotency keys on every mutation, so the duplicate-webhook class of bug died at the schema. Reconciliation became a daily job — gateway files and bank statements matched automatically each morning, exceptions queued with reason codes, write-offs requiring a name and a sign-off.

Weeks 7–8: the parallel run. Old and new systems ran together, every transaction posting to both, an automated comparator diffing the results daily. Each discrepancy was investigated to root cause — every one a bug caught in rehearsal instead of production. When the diff held at zero for ten consecutive days, we cut over: one Sunday morning, a checklist, no heroics, no drama, no surprises. The old balance column was retired to read-only, kept as a monument to the era when balances were opinions.

The result

The books balance daily, and have since cutover. The month-end negotiation meeting no longer exists — that’s the outcome I’m proudest of, because meetings that exist to argue about which number is true are the purest symptom of ledger drift, and killing the meeting means killing the disease. Reconciliation went from a week of archaeology to a morning review of a short exception queue. The engineering team ships payment features again, because the ledger stopped being haunted: with append-only history and replayable projections, mistakes became diagnosable instead of terrifying.

Precise volume and performance figures are the client’s to share, and this page runs on the same rule as the rest of the site: no number ships unless it survives a reference call. What I can offer instead is the reference call itself — serious prospects get it on request.

What it means for you

If your balances are a column and your corrections are UPDATEs, you have this problem — you just haven’t measured it yet, and the measuring is the scary part that stops being scary once it’s scheduled. The path is proven and staged: forensic reconciliation to find the truth, the recon layer alone if that’s all you need, the full core when you’re ready, parallel runs throughout so nothing is bet on a weekend. The architecture is documented publicly — why ledgers drift, the schema-level design, double-entry for engineers — and productised as the Ledger Platform for teams that want the foundation pre-built.

The 4 PM “difference kahan se aaya” ritual is not a personality trait of finance teams. It’s an architecture bug, and it’s fixable in a quarter.

The three lessons worth stealing

Forensics before construction. The temptation in every rescue is to start building the clean new thing immediately — but until the drift’s causes are named and counted, the new system just inherits the old system’s ghosts through migration. The two-week shadow-ledger replay cost impatience and paid in certainty: we knew exactly which classes of corruption existed, which meant we knew exactly what the new core had to make impossible.

The parallel run converts fear into a checklist. Nobody trusts a new ledger on faith, and nobody should. Ten days of diff-zero is an argument no meeting can produce — the sceptics watched the comparator instead of debating, and the cutover decision made itself. Rehearsal is cheaper than confidence and more durable.

Kill the meeting, not just the bug. The success metric was never technical — it was that the month-end negotiation stopped existing. Systems work earns its keep in the meetings it deletes, the overtime it returns, and the fear it retires. If a rebuild doesn’t change the calendar, it changed nothing.

/services/fintech — the practice · /work/migration — the method under harder constraints · /blog/why-your-ledger-drifts — the failure mode · /products/ledger-platform — the foundation, productised

Want books this boring?

/contact — bring your current schema and last month’s unexplained difference. The first call tells you which stage of this story you’re in, and the forensic fortnight tells you the rest.