Your balance isn’t money. It’s a record of what you’re owed.
The real rupees sit in an escrow account at a bank. Paying Ravi or a tea stall only changes whom they’re owed to.
Ravi has ₹1,000. Two ₹800 payments arrive at once.
Bad: Read, check, write
Both read ₹1,000, both pass: ₹1,600 leaves.
Good: One conditional UPDATE
Debit only if balance ≥ ₹800. The second re-checks ₹200 and is refused.
10,400
money movements a second when a sale opens
60 million a day, 15× at a festival-sale opening. That needs 16 database shards, and 15 of every 16 transfers cross between them.
No transaction spans two shards. Where is the ₹500 meanwhile?
It sits in a clearing account between shards, never invisible. A transfer row tracks each step; Ravi’s shard records credit or reject exactly once.
Sale morning: 1,900 payments a second hit one merchant. One row takes 500.
The trick
Credits can’t overdraw: make them lock-free inserts into 16 buckets, folded each second. Debits check the folded sum, never too high.
Asha’s bank debited ₹2,000 at 10:00:20. The gateway knew at 10:52.
One gateway marks such payments failed at 10 minutes, yet polls the bank for 3 days. Up to 45,000 top-ups a day succeed late.
Make every top-up land or go back
- Reserve limit headroom before the gateway order
- Credit once, only when the gateway confirms
- “Failed” isn’t final: keep listening 3 days
- Reconcile daily: gateway file, escrow statement
Remember
A wallet is a ledger with a product on top. Debit only if covered, in one transaction with the entries; reconcile daily against the banks.