Most apps are designed as if the network is always there, and treat a lost connection as an error. But users go into basements, lifts, rural areas, aircraft, warehouses and hospitals with thick walls. An offline first app flips the assumption: it is designed to work fully on the device, and treats the network as something that is useful when available. For many business apps this is the difference between a tool people trust and one they work around with paper.
Offline-capable vs offline first app design
There is a spectrum:
- Online only. Every screen loads from the server. No connection, no app.
- Cached. Recently viewed data is shown offline, read-only. Better, but users cannot do anything.
- Offline first. The app reads from and writes to a local database on the device. Users can view, create and edit data with no connection. A background sync process exchanges changes with the server whenever possible.
Offline first is more work to build, so the first question is whether you need it.
When offline first is worth it
- Field work: inspections, surveys, deliveries, maintenance visits, meter readings and sales visits in places with patchy coverage.
- Warehouses, factories and large buildings where Wi-Fi has dead spots.
- Travel and remote locations, including users who roam abroad without data.
- Speed-critical tools. Reading from a local database is near-instant, so even well-connected users get a snappier app.
- Cost-sensitive users who limit mobile data use.
It is usually not worth it for apps whose core function is inherently online, such as live chat, video calls, real-time trading or payments, though even these benefit from showing cached data gracefully.
How an offline first app works
1. A local database is the app's source of truth
The interface reads and writes a database on the device, typically SQLite or a layer built on it, such as Room on Android or Core Data and SwiftData on iOS, or an equivalent in cross-platform frameworks. The screen never waits for the network to show data.
2. Changes are recorded in an outbox
When a user creates or edits something, the app saves it locally and adds an entry to a queue of pending changes, sometimes called an outbox. The user sees their change immediately, perhaps with a small "not yet synced" marker.
3. A sync process runs when it can
When connectivity is available, the app sends pending changes to the server and fetches changes made elsewhere, usually by asking for "everything changed since my last sync". Each record carries a unique ID generated on the device, so records created offline do not clash, and a timestamp or version number for detecting changes.
4. Conflicts are resolved by clear rules
If two people edit the same record while offline, the server receives conflicting changes. You must decide in advance what happens:
| Strategy | How it works | Suitable for |
|---|---|---|
| Last write wins | The most recent change replaces the other | Low-stakes data where occasional overwrites are acceptable |
| Field-level merge | Changes to different fields are combined; only same-field edits conflict | Forms and records edited by several people |
| Server authority | The server applies business rules and may reject a change | Stock, bookings, money |
| Ask the user | Both versions are shown for a person to choose | Important documents where silent loss is unacceptable |
| Append only | Records are never edited, only added, avoiding conflicts | Logs, readings, inspection results, notes |
Designing data as append-only events where possible, for example "reading recorded" rather than "reading updated", removes many conflicts at the source.
Design decisions that matter
Decide what must be available offline
Downloading the entire company database to every phone is neither practical nor safe. Define the working set: for a technician, today's and tomorrow's jobs, the relevant customer and equipment details, and the forms needed. Sync that, and fetch other data on demand when online.
Show sync status honestly
Users need to know whether their work has reached the office. A clear indicator ("All changes synced" or "3 changes waiting to upload") and the time of the last successful sync build confidence. Never silently drop a change that failed to sync; surface it and let the user retry or fix it.
Handle server-side rejections
A change accepted locally may be rejected by the server, for example because a booking slot was taken meanwhile. Plan how the app tells the user and what they can do next.
Mind background limits
iOS and Android restrict what apps can do in the background to save battery. Background sync is opportunistic, not guaranteed. Sync when the app opens, when connectivity returns and when the user explicitly asks, and use the platforms' background task APIs as a bonus rather than the only mechanism.
Protect data on the device
An offline app stores business data on phones that can be lost or stolen. Encrypt sensitive local data, require authentication to open the app, limit how long data is kept, and provide a way to wipe app data remotely, for example on the next sync after an account is disabled. In short, treat the phone as an untrusted location.
Plan for schema changes
When the app updates and the local database structure changes, existing data and unsent changes must be migrated safely. Users may also run old app versions for weeks, so the server API must accept their sync requests.
Testing offline behaviour
- Use airplane mode and network throttling during everyday testing, not just in a final check.
- Test interrupted syncs: connection lost halfway through an upload.
- Test two devices editing the same record offline, then syncing in both orders.
- Test long offline periods with many queued changes.
- Test app updates with unsynced data on the device.
Backend requirements
Offline first is not only an app feature. The backend needs endpoints that return changes since a given point, accept batches of changes idempotently (so a retried upload does not create duplicates), apply conflict rules and record deletions so devices can remove them too. Our mobile app development team designs the app and sync backend together, and a well-indexed database keeps "what changed since" queries fast as data grows.
Key takeaways
- Offline first apps read and write a local database and sync in the background.
- They are essential for field and low-connectivity work and make every app feel faster.
- Decide conflict rules per data type; append-only designs avoid many conflicts.
- Show sync status clearly, protect on-device data and test interrupted and conflicting syncs.