ENGINEERING
Why every balance must come from a double-entry ledger
July 27, 2026 · 9 min read · Coreza
Every banking system has a table that answers the most important question in the product: how much money does this customer have? The design decision that separates reliable cores from fragile ones is whether that number is stored — a column somebody updates — or derived — the sum of an append-only ledger. It sounds like an implementation detail. It is the difference between a system that can prove its balances and a system that can only assert them.
This is the most consequential architecture decision in a fintech core, and it is almost invisible in a demo. Two products can look identical on screen while one updates a balance column in place and the other derives every balance from a double-entry ledger. The difference surfaces later — in reconciliation breaks, in support tickets nobody can explain, and in audits.
What double-entry means in an engineering context
Double-entry bookkeeping is five centuries old, but in a banking backend it is not an accounting formality — it is an invariant the database enforces. Every movement of money is a transaction with at least two entries: one account is debited, another is credited, and the entries sum to zero. Money is never created or destroyed by an UPDATE statement; it only moves between accounts, and the move itself is the record.
A customer balance is then a projection: the sum of all ledger entries touching that account. Cached for performance, yes — but always recomputable, and the recomputation is the truth. If the cache and the ledger ever disagree, the ledger wins, and the disagreement itself is a signal something needs investigating.
The zero-sum invariant gives you a property no stored-balance design can offer: the whole system can be checked. Sum every entry across every account — customer wallets, fee income, provider settlement accounts, suspense — and the total is zero. Any bug, race or partial failure that loses money breaks that equation and becomes detectable, usually the same day.
How stored balances drift
The failure mode of the balance-column design is not dramatic. It is a slow drift produced by ordinary production traffic:
- Concurrency: two withdrawals read the same balance at the same moment, both pass the check, both write. Without the ledger there is no record of what the balance should have been.
- Retries and partial failures: a payment provider times out, the client retries, and the credit lands twice — or a crash between "update balance" and "record transaction" leaves the two permanently inconsistent.
- Manual operations: a support engineer fixes a complaint with a direct UPDATE. The customer is happy; the money that appeared has no origin, and no report will ever explain it.
- Fees and rounding: a fee calculated in one place and applied in another, a currency conversion rounded differently on each side — fractions of a cent that accumulate into real discrepancies.
The rules a ledger forces on you — all of them good
Committing to derived balances imposes discipline on the rest of the core. These constraints feel strict on day one and turn out to be the reason the system stays correct in year three:
- Integer amounts in minor units — cents, satoshis, wei — never floating point. Binary floats cannot represent 0.10 exactly; a ledger that must sum to zero cannot be built on numbers that almost add up.
- Immutable entries: a posted entry is never edited or deleted. Mistakes are corrected the way banks have always corrected them — with a reversing entry that leaves both the error and the correction on the record.
- Idempotency: every operation carries a key, so a retried request posts once. The ledger makes duplicates visible; idempotency prevents them.
- Atomicity: the debit, the credit and the business-state change commit together or not at all. No code path updates a balance outside a ledger transaction — including administrative adjustments, which become ordinary, attributable entries instead of silent overwrites.
Reconciliation: proving it against the outside world
The internal invariant proves the system is consistent with itself. Reconciliation proves it is consistent with reality. A fintech core holds positions with external parties — banking rails, card processors, blockchain networks — and each of those keeps its own version of the truth. Daily reconciliation compares every provider statement and every on-chain position against the corresponding ledger accounts and forces every difference to be explained: an in-flight settlement, a provider fee not yet posted, or a genuine break that gets a suspense entry and an owner the same day.
Reconciliation is where the architecture pays for itself. With a double-entry ledger, a break is a bounded search: the day it appeared, the accounts it touched, the entries involved. With stored balances, the same investigation starts from a number with no history — which is why unreconciled differences in balance-column systems tend to be written off rather than resolved.
Crypto assets raise the stakes. An on-chain balance is public: anyone can compare the wallets you control against the balances you show customers. Self-custody without a ledger that reconciles to the chain daily is a discrepancy waiting to be discovered by someone outside the company.
What auditors and regulators actually ask
Sooner or later a regulated fintech faces some version of the same question: prove that customer balances are right. The practical answer is a chain of evidence — every balance derives from an append-only ledger; the ledger sums to zero; it reconciles daily against every external position; and an immutable, hash-chained audit trail records who initiated every movement, from which device, under which approval.
Teams that build on a stored-balance design answer these questions with forensics — reconstructing history from application logs and provider exports, at the worst possible time, under a deadline. Teams with a ledger answer them with a query. The audit does not create the requirement; it only reveals whether the architecture met it all along.
The test to run on any core banking platform
If you are evaluating a platform — or reviewing the one you built — the questions take five minutes to ask and the answers are hard to fake:
- Where does the number on the customer’s screen come from? If the answer is a balance column and not a ledger projection, everything else is decoration.
- Can a balance be changed without creating ledger entries? Ask specifically about admin tools and support workflows — that is where silent UPDATEs hide.
- Are amounts integers in minor units end to end, including the crypto side?
- Show me yesterday’s reconciliation: every provider, every chain, every difference explained. A platform that cannot show this does not do it.
- How is a posting error corrected? The only good answer is a reversing entry, attributed to a person, behind an approval flow.
Where Coreza stands
Coreza is built on the strict version of this design: every balance — fiat and crypto — derives from a double-entry ledger; amounts are integers in minor units everywhere; posted entries are immutable, with corrections as reversing entries behind maker-checker approval; and every instance reconciles daily against every connected provider and every chain it operates on. The audit trail is append-only and hash-chained, recording the who, when and from-where of every movement.
None of this is visible in a product demo, which is precisely the point of this article: the ledger is the part of a core banking platform you cannot evaluate by looking at screens. A version of this core has been processing real customers and real money at a regulated European fintech since 2024 — and the five questions above are the ones we suggest you put to any platform, ours included.
Ready to see your bank running?
Tell us about your project and we will get back to you with a live walkthrough and a tailored quote for your market.
Book a meeting