Double-Entry Ledger Architecture: How FinTech Platforms Track Money at Scale
Introduction
The fastest way to lose trust in a FinTech product is a balance that does not match reality.
Teams often start with a users.balance column updated on every transaction. It works until concurrent writes, partial failures, refunds, chargebacks, and multi-currency conversions expose gaps. You cannot explain to an auditor why row 47,291 shows $1,024.37 when the sum of transactions implies $1,019.37.
Double-entry ledger architecture treats money movement as immutable journal entries. Balances are computed. Corrections are new entries. Reconciliation becomes possible because the books always balance.
Section 1: Core Concepts
Accounts
Every pool of value is an account:
user_wallet:usr_123,platform_settlement,fees_revenue,provider_clearing:stripe.
Accounts have a type (asset, liability, revenue, expense) and currency.
Journal entries
A transaction posts N lines where sum(debits) = sum(credits) in each currency.
Transfer $50 user A → user B:
Debit: user_wallet:A $50
Credit: user_wallet:B $50
Posting rules
Encode business logic as rules: "payment capture creates these entries," "refund creates compensating entries linked to original_tx_id."
Section 2: Implementation Patterns
Append-only storage
ledger_entries table: never UPDATE or DELETE. Index by account_id, transaction_id, created_at.
Balance materialization
Derive balance from entries for audit. Optionally maintain balance_snapshots updated asynchronously for fast reads—rebuild from entries if drift detected.
Transaction grouping
transaction_id groups all entries for one business event. Status on the group: pending, posted, reversed.
Precision
Store amounts as integers in minor units (cents, paise). Never float. Document rounding rules for FX.
Section 3: Scaling the Ledger
At millions of entries per day:
| Challenge | Approach |
|---|---|
| Write throughput | Partition by account_id hash |
| Hot accounts | Serialize per account with row locks or account-level queues |
| Reporting | Read replicas + pre-aggregated daily balances |
| Historical queries | Archive cold partitions to object storage |
Shard by tenant_id for B2B FinTech—most queries are tenant-scoped.
Section 4: Common Mistakes
- Updating balances in place without entries,
- Missing fee lines (platform revenue invisible),
- No link between provider events and ledger groups,
- Float arithmetic causing cent drift,
- Allowing negative balances without explicit overdraft product rules.
Section 5: Reconciliation Loop
Σ ledger entries (by account, by day)
= provider settlement report
= bank deposit (adjusted for timing)
Automate mismatch detection. Human analysts resolve exceptions with case tooling.
Conclusion
A production FinTech ledger is an append-only, double-entry system with posting rules, integer precision, and automated reconciliation. If you cannot replay entries and reproduce every balance, you do not have a ledger—you have a guess.
Related reading:
- Payment Gateway Architecture
- Concurrency in Distributed Systems
- Transactional AI Agents and Database Consistency
For backend architecture: