Ledger systems must be correct in two senses: producing accurate financial statements and gatekeeping which transactions are allowed in. Version locking (tracking an account_version on entries, distinct from same-table optimistic locking) is a common way payments engineers prevent double-spend race conditions, but it causes thread contention on frequently updated accounts such as pools of funds. Accounts that don't need real-time balance checks are better served by end-of-day balance snapshots rather than forcing every write through strict version locking, and balance should not simply live as a column on the Account table since its use case determines where it should be stored.

6m read timeFrom news.alvaroduran.com
Post cover image
Table of contents
How to create money out of thin airOptimistic engineers choose locking at their own perilBalance is not a property of an Account

Questions this post answers

Why does version locking on a ledger account cause high latency for frequently updated accounts?

Version locking rejects any transaction whose account version has changed since it was read, forcing retries. Accounts updated very often, such as pooled funds accounts that aggregate many deposits and withdrawals, experience heavy thread contention because most concurrent writes get rejected and must retry, driving up overall latency even though these accounts rarely need strict real-time balance checks. Engineers weighing locking strategies for high-traffic ledger accounts can track this kind of design trade-off on daily.dev.

What is the difference between standard optimistic locking and the account-version locking used in ledger systems?

Standard optimistic locking, like the version column pattern in ActiveRecord, is scoped within the same table being updated. Account-version locking used in ledgers instead stores the version in a separate Entries table via an account_version column, which references the Account's version at the time each entry was recorded, preserving monotonic ordering of entries across a different table than the one being versioned. Anyone architecting ledger data models can find these distinctions on daily.dev before picking a locking scheme.

Should account balance be stored as a column on the Account table in a ledger system?

Not necessarily; whether balance belongs on the Account table depends on whether it is used for real-time integrity checks or for reporting. Accounts needing real-time checks cannot risk stale or inconsistent balance data, while accounts functioning as pools of funds can safely use an end-of-day balance stored directly on the Account table without risking data integrity issues. Developers deciding how to model balances in a ledger schema can follow this kind of guidance on daily.dev.

3.4K Impressions