Why an expense app should work with no signal
Basements, flights, foreign SIMs and lifts. What offline-first actually means, and what quietly breaks without it.
4 min read
The restaurant with the good food is in a basement. The trek starts where the signal stops. Your new foreign SIM activates the day after you land. Somehow, the places you spend money in groups are exactly the places with no bars, and most expense apps treat that as an unusual condition rather than the normal one.
What "offline" usually means in practice
Most apps are server-first: the phone is a window onto a database somewhere else. Tap add, and the app asks the server to write it. With no connection you get one of three outcomes, and all three are bad:
- The spinner. Fifteen seconds of nothing, then a timeout. You put the phone away.
- The lost entry. The form clears, the error toast disappears before you read it, and the expense simply never existed.
- The double. You tap add twice because the first one didn't seem to work. Both eventually arrive. Now the group's balances are wrong in a way nobody spots until settle-up.
The expensive failure isn't any of those, though. It's the fourth one: you see there's no signal, you decide to add it later, and later never comes. A trip loses ₹4,000 that way and no error was ever shown.
What offline-first means instead
Offline-first inverts the relationship. Your device holds the data; the server is where devices meet to agree. Concretely:
- Reads never touch the network. Opening the app, scrolling a month, checking a balance. All of it comes from local storage, so it's instant on a train and instant on wifi. The speed isn't a bonus feature, it's the same property as the offline support.
- Writes commit locally, then queue. The expense is real the moment you save it. Sync happens when there's a network, in the background, without you thinking about it.
- The queue survives. Close the app, fly for nine hours, land, open it, and the entries you made at 30,000 feet upload themselves.
That's how SplitPocket works: reads come from your device, changes sync when you're back. There is no offline mode to switch on, because there's no online mode to fall out of.
Four questions to ask any app you're evaluating
- Turn on aeroplane mode and open it. Do you see your data, or a loading state? This single test sorts most apps into two piles in about four seconds.
- Add an expense in aeroplane mode. Does it save, or does it argue?
- Force-quit, then reopen, still offline. Is the entry still there? A queue that only lives in memory isn't a queue.
- Reconnect. Does it sync by itself, or wait for you to pull-to-refresh in the right screen?
Why this is a design decision, not a feature
You can't add offline support to a server-first app as a checkbox. It changes where the truth lives, how identifiers are generated, what happens to an edit made in two places, and what the UI shows while something is pending. Teams either build it in from the start or ship a cache and call it offline.
The visible symptom of the difference is boring and constant: an offline-first app opens instantly, always, on the worst network you have. That's most of the reason logging an expense in SplitPocket takes seconds rather than "seconds, when it's working".
The habit it protects
Shared-expense tracking only works if everyone logs things as they happen. Every second of friction between "I paid" and "it's recorded" is a chance for the entry to never exist, and a ledger with holes in it is worse than no ledger, because people trust it. Offline-first is, in the end, a way of removing the best excuse anyone has.