Skip to main content

Your ledger is losing money and tests will not show it

A developer highlights race condition bugs in payment systems that standard tests miss, releasing an open-source repository to expose them.

AI-written
Inewgen
25 Sep 2026Source: Dev.to2 min read (0 views)
Share
Your ledger is losing money and tests will not show it

Stock photo for illustration only, not from the actual event

Font size
  • Most financial bugs stem from concurrency issues rather than flawed mathematical formulas.
  • Simultaneous read and write operations can cause funds to vanish without triggering application errors.
  • The ledger-core GitHub repository demonstrates these failures using three distinct concurrency strategies.
  • Enforcing strict invariants at construction and using integer minor units prevents rounding errors.

Most of the bugs encountered in payment systems are not logic bugs. The formula was correct, the rounding was accurate, and the tests passed successfully. Yet, money still went missing because two separate users performed actions at the exact same moment.

Working on transaction and settlement systems reveals how quietly this specific class of bug fails. A null reference throws an immediate error, and an incorrect formula surfaces during the initial test. However, a lost update merely makes a number slightly incorrect on a single day for a single account, going completely unnoticed until reconciliation runs.

database server rack data center

Stock photo for illustration only, not from the actual event

To make this failure visible, a small repository named ledger-core was built on GitHub. It operates as a double-entry ledger incorporating three concurrency strategies behind a single interface, alongside a test suite that proves which methods successfully conserve funds.

Race conditions in financial software represent a critical blind spot for developers. Because modern backend systems frequently execute parallel threads to handle high transaction volumes, traditional unit testing often fails to replicate real-world data collisions. Robust concurrency controls and strict architectural patterns are therefore essential to maintain ledger integrity.

The fundamental rule of any ledger is straightforward: the sum of all balances after any number of transfers must equal the sum before them. Transfers merely move money without creating or destroying it.

3Concurrency Strategies

The naive approach of reading a balance, calculating a new value, and writing it back fails under concurrent load. If two threads read a balance of 1,000 simultaneously, one adds 100 while the other subtracts 50, the final write overwrites the first, causing the initial transfer to vanish without logging or failing.

Never miss the latest news?

Subscribe to get news summaries by email - not often enough to be annoying.

โฆษณา

"That SpinWait is the honest part. The window exists in real code too. It is just narrower, which means you hit it on a Tuesday in production instead of every time in CI."

ledger-core developer

Source: Dev.to

Comments

Leave a Comment
0/2000

Found something wrong in this article? Report an issue with this article