Skip to content
Writing

14 August 2026 / 4 min read / Fintech, Databases

Never store a balance

Why every wallet I build now uses a double-entry ledger, and the five lines of code that make it work.

By Emmanuel Olowu

Hand holding a phone with a finance app

The first wallet I built stored the balance as a number on the user row. It worked until two requests updated it at the same time, and a customer was briefly richer than they should have been.

Balances are a query, not a column

In a double-entry ledger, every movement of money writes two entries that sum to zero. A balance is never stored. It is calculated from the entries.

select coalesce(sum(amount), 0) as balance
from ledger_entries
where account_id = $1;

That one decision removes a whole class of bugs. You cannot forget to update the balance, because there is nothing to update.

What you get for free

  • An audit trail. Every change has a reference, a time and a counterpart.
  • Reconciliation. Totals per account should match the payment provider. When they do not, you know exactly which day to look at.
  • Safe retries. Make the reference unique and a replayed webhook simply fails to insert.

When it is overkill

If nothing in your product holds value between transactions, you do not need this. The moment users can top up, hold or withdraw, you do.