What a Financial Ledger Is and Why Teams Outgrow Spreadsheets
Post your first omnibus settlement
Clone the Formance Ledger repository on GitHub, run it locally, and post the omnibus settlement from this article as your first transaction.
Post your first omnibus settlement
Clone the Formance Ledger repository on GitHub, run it locally, and post the omnibus settlement from this article as your first transaction.
Every payments or embedded-finance product runs on one record of who owns what, and the engineering leader ends up owning the decision of where that record lives. Most teams start with a reconciliation workbook and a balance column in an application table. Teams only ask what a financial ledger is once the workbook and the balance column stop agreeing on financial transactions.
A reconciliation mismatch usually exposes the problem. Your omnibus account, the single bank account holding funds on behalf of all your customers, shows one balance. The workbook that attributes that balance to individual customers sums to a different one. An engineer fixed last month's settlement by typing a new value over the old cell, and nobody can produce what the cell said before the edit. Your banking partner has now asked for daily reconciliation records, starting next quarter.
If you cannot show how each customer balance was built from postings, the partner can pause onboarding or flag the account until you can.
A financial core ledger prevents mismatches by rejecting write postings that don't balance, so the omnibus total and the sum of customer balances cannot drift apart without a posting that explains the difference.
A financial ledger is an append-only record of postings built on double-entry accounting, where every transaction balances and every balance derives from the underlying postings. A customer's balance in a ledger is the sum of every posting that interacted with the account.
A spreadsheet stores balances as editable cells with no enforced relationships between cells, so it cannot guarantee balanced, traceable money records. In a spreadsheet, anyone with editing rights can replace a cell's formula with a constant.
A ledger and a spreadsheet differ in what they guarantee. A ledger derives every balance from postings and rejects any write that does not balance. A spreadsheet accepts any edit to any cell and keeps no link between the customer total and the bank total.
An operational core ledger records money in motion in real time and sits beneath the enterprise resource planning (ERP) system. In an illustrative case, the core ledger knows a settlement arrived at 14:02 and which of 40,000 customers each dollar belongs to. The general ledger in the ERP closes the books at month-end using the core ledger's output.
Formance is an open-source, programmable core ledger that unifies fiat and digital assets with regulatory-grade traceability. It rejects any write whose postings do not balance, so the omnibus total and the sum of customer balances cannot drift apart without a posting that explains the difference.
Spreadsheets fail as a system of record in four ways: they let history be overwritten, they don't enforce balanced books, they cannot reject duplicate settlements, and they break down as payment volume grows.
An overwrite destroys the prior value and, with it, any proof of what the balance was before the correction. A system of record for money has to answer "what did we believe this customer owned on the 14th" after the 15th's correction has landed.
In an immutable ledger, the correction is a new posting that reverses the first and posts the right amount, and both remain readable for as long as the ledger exists. In a workbook, the fix and the error share the same cell, and the error disappears the moment you save the fix.
A workbook can hold a customer total that doesn't match the bank total because no rule connects the two cells.
A reconciliation tab with 2,000 rows can hold a customer total that disagrees with the bank total, and nothing in the file flags it. Two analysts each paste a provider report into the same tab, or one analyst overwrites a settlement row to match the bank. The SUM at the bottom still returns a number, and it cannot tell you which cells caused the mismatch.
A ledger refuses the write when the postings do not sum to zero, so the imbalance never reaches storage.
Pasting a settlement file twice counts the settlement twice, and the workbook cannot identify the second paste as a retry.
An automated import also counts a settlement twice if the first attempt appears to time out but succeeds, and the retry also succeeds. Two analysts loading the same provider report into the same tab an hour apart cause the same duplicate.
Under idempotent writes, the same settlement submitted again under the same identifier produces exactly one transaction. A cell cannot carry the identifier at all.
Payment volume keeps growing. United States noncash payments reached 236.6 billion in 2024 and have more than tripled since 2000.
Manual reconciliation breaks at these numbers because every added payment is another row someone has to match by hand. A person comparing provider files to bank statements row by row can only check so many rows per day, so the backlog grows with volume.
Each manual match also adds a chance of a typo, a double paste, or an overwritten value, and none of those leave a trace in the workbook. Daily reconciliation requirements make this worse, since you have to finish matching again every day before the next batch arrives.
Move your spreadsheet numbers to a core ledger when any one of these five signals is true. The signals are unattributable omnibus balances, multiple payment rails, corrections that erase history, requests for non-rewriteable records, and engineering time lost to reconciliation fixes. Each signal has a yes/no test you can run against your current setup this week.
If nobody on your team can attribute every dollar in the omnibus account to a named customer from your own records, the bank statement does not answer the question the regulator asks.
Regulators overseeing safeguarded customer funds expect firms to keep records that match the funds held for clients, reconcile those funds regularly and log when each reconciliation ran and what it found.
Fintechs that reconcile in only one direction can miss funds that are commingled between customers and the firm. Pick a customer in the omnibus account at random, and ask: can you produce their balance from postings rather than from a cell?
Two settlement formats arriving into one balance column is already more than a workbook can attribute. A card acquirer settles on one cutoff in one file layout, an automated clearing house (ACH) originator uses another, and a digital-asset custodian confirms by block.
A spreadsheet has no concept of a source account, so once the second payment rail posts, you can't trace the discrepancy back to the rail that caused it.
Count the rails that post into your customer balances. If the count is above one and your record does not carry the rail of origin on every row, the answer is yes.
If a correction has ever replaced a value and you cannot reproduce the pre-correction balance as of a past date, your record lacks bi-temporality, which tracks when an event was recorded and when it was effective.
An ACH return that lands five days after the original credit must be recorded on the day it arrives and applied to the day the credit was effective, and both dates must survive. A cell holds at most one date, and usually neither.
Take last month's largest correction and ask what the record showed for that customer on the day before you fixed it. Bi-temporal records make that query answerable.
A spreadsheet cannot satisfy a request for records that cannot be altered, because its entire storage model is alteration. Financial regulators require fintechs to keep records in a form that cannot be rewritten or erased, or to keep an audit trail that can recreate the original record after it's been modified or deleted.
Banking partners and auditors increasingly ask for the same guarantee. If a partner or regulator has asked for immutable records, treat the request itself as the signal.
If a reconciliation fix has displaced planned product work in the last two sprints (development cycles), the spreadsheet is costing engineering capacity, not just finance capacity.
Gartner's July 2023 survey found that 18% of accountants made financial errors at least daily under capacity constraints, and a third make several errors every week. Engineering teams absorb the work of tracing financial errors through application tables.
Open your last three sprint boards and count the tickets that exist because two numbers disagreed. Three or more is the threshold.
A core ledger records an omnibus settlement as one atomic transaction. Balanced postings attribute funds to customers and fees, and it rejects duplicate references. A correction is added as a new entry next to the original.
The transaction is written in Numscript, Formance's purpose-built language for describing financial transactions. An engineer and a finance lead can both read the intent of a money movement in it.
A settlement into an omnibus account is one atomic transaction with several postings that sum to zero, and the ledger commits all of them or none. The transaction posts a $2,000,000.00 settlement from a payment provider and attributes it to two customer balances and a fee account in a single write.
The account model uses @counterparties:paymentProviders:provider:settlement as the provider boundary, @users:48213:available and @users:51977:available for the customers' available funds, and @platform:revenue:fees for the platform's fee income.
// OMNIBUS_SETTLEMENT
// Event: a provider settlement funds two customers and platform fee income
send [USD/2 200000000] (
source = @counterparties:paymentProviders:provider:settlement allowing unbounded overdraft
destination = {
max [USD/2 125000000] to @users:48213:available
max [USD/2 69000000] to @users:51977:available
remaining to @platform:revenue:fees
}
)
set_tx_meta("event_type", "omnibus_settlement")
set_tx_meta("settlement_id", "settlement")
USD/2 means United States dollars with two decimal places, so 200000000 is $2,000,000.00.
The source account counterparties:paymentProviders:provider:settlement is the ledger's boundary with the provider. The $2,000,000.00 leaving it is the amount that should appear on the omnibus bank statement for that settlement date, which is what reconciliation checks.
Customer 48213 receives $1,250,000.00, customer 51977 receives $690,000.00, and the remaining $60,000.00 lands in platform:revenue:fees. The source movement and the three destination postings sum to zero. If any one of them cannot be applied, none of them is.
The example uses settlement as the provider's settlement file identifier in metadata. The transaction also carries the identifier as a reference.
Formance Ledger stores the reference and uses a rule to prevent duplicate references. A retried import with the same reference is rejected instead of posted a second time, so storage enforces idempotency.
Every balance in the result is derived from postings, so users:48213:available cannot be edited to a different number.
If the provider later reports the fee should have been $58,000.00, you post a reversal and a corrected transaction effective on the original settlement date.
The original transaction remains in the hash-chained history, where each transaction is cryptographically linked to the previous transaction. Each posting keeps both the date you learned about the event and the date the event applied.
Ensuring ledger integrity requires following the full set of rules: balanced writes, immutable history, idempotent references, and atomic commits.
Your spreadsheet is no longer a system of record if you cannot produce the full chain of postings behind any omnibus balance in under an hour.
Before your next reconciliation day, pick your largest customer balance and the date of your last correction, then reproduce that balance as of that date from its postings. If you cannot, the spreadsheet stopped serving as your system of record when the first cell was overwritten.