If you have ever worked with numbers in code, using a float or double feels natural. But in financial systems, that instinct can quietly introduce errors that scale into real money loss.
This is not theoretical. It is one of the first problems engineers run into when building payment systems, wallets, or ledgers.
Let us break down how real systems handle money, and why.
The Problem with Floating-Point Numbers
Floating-point numbers store values in binary. That works well for many computations, but it cannot represent most decimal fractions exactly.
A simple example:
0.1 + 0.2 is not exactly 0.3.
Instead, you get something like:
0.30000000000000004
In isolation, this looks harmless. But now imagine a system processing millions or billions of transactions.
Even a tiny error like ₹0.01, repeated enough times, becomes a serious discrepancy. In financial systems, this is unacceptable.
The Core Rule
Financial systems follow a strict rule:
Never use floating-point numbers for money.
Instead, they use representations that guarantee exact precision.
There are two common approaches:
- Integers representing the smallest unit (paise, cents)
- Fixed-precision decimal types
For example:
₹100.50 → 10050 (paise)
This eliminates rounding issues completely.
How Real Systems Handle Money
To understand how fintech systems work internally, it helps to look at how transactions are recorded.
Double-Entry Bookkeeping
Every transaction creates two entries:
- A debit from one account
- A credit to another account
If you transfer ₹100:
- Your account:
-100 - Receiver's account:
+100
This ensures that the system always remains balanced.
Append-Only Ledger
Transactions are never modified or deleted.
Instead, systems use an append-only ledger:
- Every entry is recorded once
- Corrections are made by adding new entries, not editing old ones
This provides auditability, traceability, and safety against corruption.
Balance Is Not the Source of Truth
In many systems, the balance you see is not the primary data.
The real source of truth is the ledger.
Balance is derived by summing all entries for an account. Some systems cache this for performance, but the ledger remains authoritative.
Idempotency: Handling Retries Safely
Network requests can fail and retry. Without protection, this could lead to duplicate transactions.
To prevent this, systems use idempotency keys.
Each request includes a unique key. If the same request is received again:
- The system does not process it twice
- It returns the original result
This is critical in payment systems where retries are common.
Where Strings Come In
You might notice that many APIs represent amounts as strings:
json1{ 2 "amount": "100.50" 3}
This often leads to confusion.
Strings are used at system boundaries, not internally.
Why?
- Avoid precision loss during serialization
- Ensure consistency across languages (especially JavaScript)
- Prevent accidental float parsing
Once the request reaches the backend, the value is converted into an integer or decimal type for actual computation.
A Simple Mental Model
A typical flow in a payment system looks like this:
- API receives amount as a string
- Backend converts it into an integer (smallest unit)
- Two ledger entries are created (debit and credit)
- Entries are appended to the ledger
- Idempotency is checked to avoid duplicates
- Balance is computed from the ledger
This design prioritizes correctness over convenience.
Demonstrating the Difference
If you simulate adding ₹0.01 one million times:
- Using float → you will see drift
- Using integer → exact result
- Using precise decimal → exact result
This is why financial systems are designed the way they are.
Why This Matters
At small scale, these details seem unnecessary. At large scale, they become critical.
A system handling money must guarantee precision, consistency, and auditability.
Using floats breaks that guarantee.
Final Thoughts
Financial systems are not just about moving money. They are about maintaining trust.
That is why they rely on exact numeric representations, double-entry bookkeeping, immutable ledgers, and idempotent operations.
These are not optimizations. They are requirements.
Once you understand this, a lot of design decisions in fintech start to make sense.

