Offline-first mobile apps: sync, conflicts and what users expect
Connectivity is a spectrum, not a switch. Designing for the lift, the tunnel and the weak signal changes your data model, your sync strategy and your error messages.By MI Technologies Engineering3 min read
Most apps are built as if the network were always there, then fail in lifts, trains, basements and patchy rural coverage. "Offline-first" flips the assumption: the app works against local data, and the network is something that happens in the background.
Decide whether you need it
Offline-first is real engineering cost. It is worth it when users do their work where connectivity is unreliable — field service, logistics, inspections, healthcare rounds, travel — or when instant response matters more than freshness. A catalogue browser that is useless without live prices may only need good caching and honest error states.
Be explicit about which features must work offline and which can degrade. "Everything" is rarely the right answer.
The building blocks
A local database as the source the UI reads from. Screens render from local storage, not directly from API responses. SQLite-based storage is the common foundation on both major platforms and in cross-platform frameworks.
A write queue. User actions are saved locally first, marked pending, and sent when a connection exists. The UI updates immediately, which is also what makes the app feel fast online.
A sync process. It pushes queued changes, pulls remote changes, retries with backoff, and survives the app being killed halfway through. Make each operation idempotent so a retry never creates a duplicate.
Visible state. Show what is synced, pending or failed. Users forgive delay far more readily than silent loss.
Conflicts are a product decision
Two people edit the same record offline. When both sync, something has to give. The main strategies:
- Last write wins. Simple, and fine when losing an occasional edit is acceptable. Dangerous for anything important.
- Field-level merge. Merge changes per field so unrelated edits both survive.
- Server-side rules. Some fields, such as a status moving forward only, have natural rules about what wins.
- Ask the user. For high-value data, surface the conflict and let a person choose.
Which one is right depends on the data, which is why this conversation belongs to product as well as engineering.
Practical details that bite later
- Time. Device clocks are wrong. Prefer server-assigned ordering or version numbers over trusting local timestamps for conflict decisions.
- IDs. Generate identifiers on the device (for example UUIDs) so records can be created offline without waiting for the server.
- Schema evolution. Local databases need migrations too, and an old app version may sync against a newer API.
- Storage limits and cleanup. Decide what is cached, for how long, and what happens when the device is full.
- Security. Local data is data at rest on a device that can be lost. Encrypt sensitive data and think about what happens on logout.
- Large files. Uploading photos on a weak connection needs resumable, background transfer rather than a single request.
Test the awkward conditions
Test with the network off, then flaky, then slow, then returning while a sync is mid-flight. Kill the app during a sync. Change the clock. These are the conditions your users will create, and they are the ones a demo on office Wi-Fi never shows.
What to take away
Offline-first is a data-architecture choice, not a feature. Decide what must work without a signal, store and queue locally, make sync idempotent, and treat conflict handling as a product decision made deliberately rather than discovered in support tickets.
MI Technologies Engineering
Software engineering team at Mohansh Innovations Pvt. Ltd.