Building Apps That Keep Working
When the Network Doesn't
Patchy mobile data is a design constraint, not an edge case. A practical approach to local-first storage, sync queues and honest interface states.
Many users move between strong 4G in a city centre, weak signal in transit and no data at all when a bundle runs out. Apps that assume a constant connection fail these users in quiet, frustrating ways: lost form entries, endless spinners and duplicate submissions.
Designing for intermittent connectivity changes architecture decisions early, so it is far cheaper to plan for it on day one than to retrofit it later. This is the approach we use.
Start with the local database
Treat the device as the primary home of the user's work and the server as the place it eventually syncs to. Screens read from local storage first; the network only refreshes it. On Android and iOS that usually means SQLite, directly or through a library such as Room, Drift or WatermelonDB. On the web it means IndexedDB behind a service worker.
- Render screens from local data immediately, then refresh in the background.
- Store when each record was last synced so the interface can say how fresh it is.
- Cache reference data such as product lists, branch locations and price tables aggressively: it changes rarely.
Queue writes, don't block on them
When the user submits something, write it locally and add it to an outbox queue. A background worker sends queued items when a connection is available and retries with exponential backoff. The user keeps working instead of watching a spinner.
- Give every write a client-generated ID (a UUID) so the server can safely ignore a retry that arrives twice.
- Make server endpoints idempotent, especially anything that moves money or stock.
- Keep the queue ordered per record so an edit never overtakes the create it depends on.
Decide how conflicts are resolved
If two people edit the same record while offline, something has to win. Pick a rule per type of data rather than one rule for the whole app.
Common conflict strategies
| Strategy | How it works | Good fit for |
|---|---|---|
| Last write wins | The latest timestamp overwrites | Profile fields, settings |
| Server authoritative | Server rejects stale updates; client refetches | Balances, stock, payments |
| Field-level merge | Non-overlapping field changes are combined | Notes, checklists, forms |
Be honest in the interface
People trust an app that tells them what is happening. Show a clear "saved on this phone, will send when online" state, a visible count of pending items and the time of the last successful sync. Never show a success message for an action the server has not confirmed when that action has real-world consequences, such as a payment.
Respect the data bundle
Offline tolerance and data cost go together. Compress API responses, paginate lists, resize images on the server and avoid re-downloading unchanged data with ETags or "changed since" queries. Let users choose to download large media only on Wi-Fi.
Questions product owners ask us before committing to an offline-first build.
Does offline-first make a project much more expensive?
It adds work to the data layer and to testing, but much less than retrofitting it later. Scope it per feature: not every screen needs to work offline.
Can a web app work offline too?
Yes. A progressive web app with a service worker and IndexedDB can cache the app shell and queue submissions, although background sync support varies between browsers.
How do we test it?
Use network throttling and airplane-mode testing on real low-end devices, and write automated tests for the sync queue and the conflict rules.
Want to talk to an Arki engineer?
Before any commercial conversation, we'll put you on a 30-min call with a senior engineer in your stack. No salespeople. Just a technical sanity check.
Tell us what you're working on.
We'll respond within one business day with the right next step.