Engineering
Offline first is a product decision, not a caching layer
Every team asks for offline support after the first field report. The hard part was never the cache — it is deciding what the app is allowed to promise.
Written by Denis Rudenko, Software Engineer · · 2 min read
Every field team asks for offline support after their first week without signal. The request sounds like a caching problem. It never is.
Four questions before any code
- When two devices edit the same record offline, which one wins?
- What is the app allowed to promise a user who is offline right now?
- How long may stale data stay on screen before it becomes a lie?
- What happens to a queued action the server later rejects?
Teams that answer these four questions first ship offline support in weeks. Teams that start with a cache library spend months discovering the questions one bug at a time.
Conflict resolution is a product rule
Last write wins is a decision, not a default. On a logistics app a driver's delivery confirmation must never be overwritten by a dispatcher's stale edit, so the record carries an origin and the merge rule reads it.
fun merge(local: Delivery, remote: Delivery): Delivery = when {
local.confirmedByDriver && !remote.confirmedByDriver -> local
remote.updatedAt > local.updatedAt -> remote
else -> local
}
Show the state, do not hide it
The apps that feel trustworthy offline are the ones that say what they know:
- Synced — this matches the server as of a timestamp the user can see.
- Pending — queued locally, will send when signal returns.
- Rejected — the server refused it, and here is what to do about it.
The moment an app pretends everything is fine offline, the user stops believing it when it says everything is fine online.
What it costs
| Approach | Build time | Support load |
|---|---|---|
| Cache on top of a network app | 2 weeks | High, forever |
| Local first with sync | 6 weeks | Low |
The second column is the one that decides it. A cache bolted onto a network first app generates support tickets for the life of the product.
- architecture
- mobile
- kotlin