Why your billing app has to work with no signal
Cloud-only billing fails at exactly the wrong moment. What offline-first actually means, and the duplicate problem nobody mentions.
6 min read
In short
- Reading cached data offline is easy. Completing a sale offline — stock, balance, bill number — is the hard part, and it is the part that matters.
- Offline-first means the phone is the source of truth at the moment of sale; the server is told afterwards.
- Retrying a queued sale can record it twice unless each sale carries an identifier created on the device.
- Test it in flight mode with five sales, then reconnect and count. Five must appear — not four, not ten.
Most billing apps are a website in an app shell. They work beautifully in a demo on office wifi and fail in a basement shop at 7pm when the mobile network is congested and there is a queue at the counter.
The moment you most need to bill is often the moment the network is worst: peak hours, crowded areas, congested towers.
What offline-first actually means
There is a real difference between an app that caches data for reading and an app that can complete a sale with no connection. Reading a cached product list is easy. Accepting a sale, decrementing stock, updating a customer's balance and issuing a bill number — with no server to ask — is the hard part.
Offline-first means the phone is the source of truth at the moment of sale. The bill is written to the device, and the server finds out later. The sale does not wait for permission.
The duplicate problem
Here is the part that rarely gets mentioned, and it is where most naive offline implementations break. When the connection returns, the app sends queued sales to the server. If a response is lost in transit — not the request, the response — the app does not know whether the sale was saved. So it retries.
Retry without protection and you have just recorded the same sale twice. Your stock is wrong, your day's takings are wrong, and a customer's ledger says they bought something they did not. Worse, this happens exactly when connectivity is flaky, which is when the most sales are queued.
The fix is that every sale carries an identifier generated on the device before it is ever sent. The server treats that identifier as unique. If the same sale arrives twice, the second one is recognised as a replay of the first and acknowledged rather than written again. The retry becomes safe.
What to ask before you trust an app with a rush
- Turn on flight mode and complete a full sale, including a credit sale. Does it finish?
- Do it five times, then turn the connection back on. Do exactly five sales appear on another device — not four, and not ten?
- Does stock reflect all five?
- Force-close the app mid-sync and reopen it. Is anything lost or duplicated?
The five-sales test is the one that matters. Plenty of apps pass the first question and fail the second, and you will only discover it during a month-end reconciliation that does not add up.
Sync is not backup
One last distinction. Syncing means your devices agree with each other. It does not mean you have a copy of anything if you delete it — a deletion syncs too. Keep that in mind before you rely on sync as your only safety net.
Common questions
What does offline-first mean in a billing app?
It means the app can complete a whole sale with no internet connection: write the bill, reduce stock, update the customer's balance and issue a bill number, all on the device. The server is informed later when a connection returns. An app that merely caches data for reading is not offline-first.
Can a bill be recorded twice when the connection comes back?
It can, in a naive implementation. If the app sends a queued sale and the reply is lost in transit, the app does not know whether it saved and retries — writing the same sale twice. The fix is for every sale to carry an identifier generated on the device, which the server treats as unique, so a repeat arrival is recognised as a replay rather than a new sale.
How do I test whether a billing app really works offline?
Turn on flight mode and complete five sales, including at least one on credit. Reconnect, then check another device: exactly five sales should appear, stock should reflect all five, and force-closing the app mid-sync should neither lose nor duplicate anything.
Is syncing the same as having a backup?
No. Syncing means your devices agree with each other. If you delete something, the deletion syncs too, and it is gone everywhere. Sync protects you from a lost phone, not from a mistaken deletion.
Khata is free to use
Billing, khata, stock and reports on your phone. No card, nothing to cancel.
See what you getofflinebillingsyncoffline billing app