- Client
- Northbank Clearing
- Industry
- Fintech
- Year
- 2025
- Duration
- 22 weeks
- Team
- 5 engineers, 1 designer, 1 SRE
- Services
- Platform engineering · Security & compliance · Cloud & DevOps
Northbank's settlement engine buckled every month-end. We rebuilt the ledger around an append-only core and took the closing window from nine hours to twenty-two minutes.
The product
Rebuilt interface, live figures. Everything below is the shipped surface, not a concept.
Postings / min
40,112
Close window
22 min
Open breaks
0
month-end close, minutes
Northbank settled card and ACH volume on a ledger that mutated balances in place, so the only record of what a balance used to be was last night's snapshot. Reconciliation locked accounts while it ran. Month-end close took nine hours with two people watching a progress bar, and one failed batch meant restoring the snapshot and replaying by hand from a runbook whose fourth step was, literally, ask Marco. Their auditors had started asking who was able to edit a balance directly, and nobody enjoyed the honest answer.
We remodelled the ledger as append-only double entry, which turns a balance into a projection rather than a number anyone can overwrite. Every posting is idempotent on the digest of the signed request that produced it, so replays are safe and the audit trail is the system itself instead of a report assembled afterwards. Partitioning the journal by settlement account got writes scaling sideways across the cluster. Then the unglamorous part: the new core ran in shadow against live traffic for eleven weeks, reconciling hourly against the old engine, and we did not move a single customer balance until the two agreed to the cent for thirty consecutive days.
The ledger holds 40,000 postings a minute at sustained peak with roughly three times that in headroom on the current cluster. Close fell from nine hours to twenty-two minutes and runs unattended — the first month nobody was rostered to watch it, someone came in anyway. Compute per thousand postings is down 68%. The SOC 2 Type II audit closed with no findings against the ledger, and ask Marco is no longer a step in anything.
Solid lines carry request traffic. Dashed lines are asynchronous — replication, shadow reads and audit trails that must never sit on the critical path.
INSERT INTO journal (posting_id, account_id, amount_minor, request_digest)SELECT $1, $2, $3, $4WHERE NOT EXISTS ( SELECT 1 FROM journal WHERE request_digest = $4)RETURNING posting_id, seq; CREATE MATERIALIZED VIEW balance ASSELECT account_id, SUM(amount_minor) AS balance_minor, MAX(seq) AS as_of_seqFROM journalGROUP BY account_id;A posting is idempotent on the digest of its signed request, and a balance is a projection — not a column anyone can overwrite.
The first month-end nobody was rostered to watch.
Postings cleared per minute at sustained peak, against 3,600 on the old engine
Month-end close, down from nine hours with two people watching it
Lower compute per thousand postings after partitioning by settlement account
Figures reported by Northbank Clearing after launch.
- 01Append-only double-entry core with balances as a materialised projection
- 02Idempotent posting API keyed on a signed request digest
- 03Journal partitioned by settlement account for sideways write scaling
- 04Eleven-week shadow reconciliation against the legacy engine
- 05Evidence pipeline feeding SOC 2 Type II control reviews
- Rust
- PostgreSQL
- Kafka
- gRPC
- Kubernetes
- Vault
- Datadog
“Close used to be an event we staffed for. Now it is a notification. Our auditors got a better answer than we had been able to give them.”