// CASE STUDY · FINTECH

How we built a double-entry ledger the finance team can actually reconcile.

A tangled balances table made month-end close a four-day archaeology dig. We replaced it with an append-only double-entry ledger and a daily reconciliation job — close now takes an afternoon.

ClientNDA — fintech
IndustryFintech · Ledger
EngagementCustom Build
Timeline9 weeks
StackGo · Postgres · AWS
// OUTCOMES
−87%Month-end close time4 days → half a day
100%Reconciled, every day for 18 monthsautomated, not manual
1Source of truth — an append-only ledgerbalances are derived, never edited
0Manual balance edits after cutoverimmutable by design
// THE SITUATION

Balances nobody could fully trust.

The system tracked money in a single mutable balances table that was updated in place. Over time the balances drifted from reality, there was no record of how a number got to be what it was, and month-end close had become a four-day spreadsheet reconciliation that the auditors openly disliked.

The ask was foundational: a ledger the finance team could actually trust, where any balance can be explained down to the entry that produced it.

// THE APPROACH

Double-entry, append-only, derived balances.

The fix is a hundred years old: double-entry bookkeeping. Every movement is recorded as balanced debits and credits in an append-only journal that is never edited. Balances aren't stored and mutated — they're derived from the journal, so they can't silently drift. And reconciliation runs every day, not as a month-end fire drill.

We built it alongside the old system and ran them in parallel, verifying the new ledger matched reality before anyone relied on it.

// WHAT WE BUILT

A ledger, derived balances, daily reconciliation.

  1. Built an append-only journal.

    Every transaction posts balanced debits and credits as immutable entries — corrections are new reversing entries, never edits.

  2. Derived balances instead of storing them.

    Balances come from materialised views over the journal, so they always reconcile to the entries by construction.

  3. Made the posting API idempotent.

    Idempotency keys mean a retried posting never double-counts — essential when money is involved.

  4. Automated daily reconciliation.

    A job reconciles the ledger against external sources every day and flags any break immediately, instead of at month-end.

  5. Ran it in parallel, then cut over.

    Backfilled history, dual-recorded against the old table, and only cut over once the two matched to the penny.

  6. Gave auditors a straight answer.

    Any balance can be traced to the exact entries that produced it — the audit trail is the ledger itself.

// THE OUTCOME

Close in an afternoon, explainable to the penny.

Before

Mutable balances table

  • · balances edited in place
  • · silent drift over time
  • · no audit trail
  • · 4-day month-end close
  • · auditors unhappy
After

Append-only ledger

  • · immutable journal entries
  • · derived, self-reconciling balances
  • · every balance traceable
  • · half-day close
  • · daily automated reconciliation

Month-end close dropped 87%, from four days to an afternoon, and the ledger has stayed 100% reconciled every day for eighteen months. When an auditor asks why a balance is what it is, the team shows them every entry behind it.

Close went from a four-day fire drill to an afternoon. And when an auditor asks why a balance is that number, we can show them every entry.
VP of FinanceFintech · name withheld under NDA
// WHAT WE USED

The stack and the services applied.

Tech stack
GoPostgres 15Materialized viewsAWS · ECSAWS · RDSdbtOpenTelemetryGrafanaTerraformGitHub Actions
// LET'S TALK

Is your month-end close a fire drill?

Tell us how money moves through your system. We'll tell you what a ledger you can trust looks like.