ARTICLE

Mobile

Build for the metro: offline is a product decision

Most apps are built on office wifi and used on a train. Treating the network as optional is a decision about who gets to use your product.

By Adil 4 min read

Software is written in places with excellent internet and used in basements, lifts, warehouses, moving trains and buildings with thick walls. An app that assumes a connection is an app that stops working exactly when someone needed it.

The failure mode is worse than it looks

A dead connection is not the hard case. The hard case is a connection that technically exists and delivers nothing: the request neither succeeds nor fails, the spinner turns, and the person watches it. Then they tap the button again.

Any app that will be used away from a desk needs an answer for this, and the answer has to be designed rather than discovered in production.

Three levels, increasing in cost

  • Fail honestly. Detect it, say so, keep what the user typed, offer a retry. Cheap, and enormously better than a spinner. Every app should do at least this.
  • Read offline. Cache what was already fetched so the app opens and shows something. Moderate effort, and covers most consumer cases.
  • Work offline. Actions are recorded locally and sync later. This is a real engineering project, and it is what field work actually requires.

The expensive part is not storage

Keeping data on the device is straightforward. The cost is in reconciliation: two people edited the same record while disconnected, and one of them has to lose. Or a job was marked complete twice because the first attempt did sync, silently, before the phone gave up.

Which is why the design work comes first. Give every action an identifier generated on the device so a replay cannot duplicate it. Decide per data type who wins a conflict — last write, server always, or ask the user. Show sync state honestly, because a technician needs to know whether the office has seen their work.

Offline support is not a feature you add. It is an assumption you either make on day one or retrofit at three times the price.

Deciding, in one question

Where is this used? If the honest answer includes a basement, a van, a lift, a factory floor or a train, offline is not a nice-to-have and cutting it will produce an app your users abandon. If it is used at a desk, fail honestly and spend the money elsewhere.

The delivery and field service builds in our case studies both assume offline from the first week, and both say plainly that if the budget forces a choice, cut features instead.

What syncing actually involves

“It works offline” sounds like one feature. It is four, and each has to be decided rather than discovered.

  1. A queue of intents. Not “the new state” but “what the user did” — mark job complete, add photo, change quantity. Actions replay cleanly; states overwrite each other.
  2. An identifier per action, made on the device. So the server can recognise the same action arriving twice and ignore the second. Without this, every flaky connection creates duplicates.
  3. A conflict rule per data type. Last write wins is fine for a note and wrong for a stock count. Decide per type, in advance.
  4. Visible sync state. Saved on device, sending, sent, failed. A technician needs to know whether the office has seen their work; a silent spinner is not an answer.

The conflict question, concretely

Two people edit the same record while disconnected. Both come back online. Something has to give, and pretending otherwise just means the outcome is decided by whichever request happened to arrive second.

For most business data, server-wins with the loser's version kept and flagged is the humane answer — nothing is destroyed and a person can look. For counts and totals, neither side should win: the correct answer is usually to apply both changes as deltas, or to refuse and ask. For anything with money attached, refuse and ask. Always.

How to test it, since it will not test itself

This is the part that gets skipped, and it is why offline features ship broken. Testing on office wifi proves nothing at all.

  • Use the network throttling in developer tools, and the offline mode.
  • Test the half-connection deliberately: request sent, response lost. This is the case that creates duplicates and it will not occur by accident on your desk.
  • Kill the app mid-sync. The queue has to survive being force-closed.
  • Let the device sit offline for a full day of work, then reconnect. Twenty queued actions behave differently from two.
  • Test two devices making conflicting changes to the same record.

What it costs, so you can decide

As a rough rule, a mobile app that must work offline is around twice the effort of the same app online-only. Not because storage is hard, but because every feature now has a disconnected path, a sync path and a conflict path, and all three need building and testing.

That is a real number and it deserves an honest decision rather than being discovered in month three. If the app is used at a desk, spend the money on features. If it is used in a van, spend it here — because the alternative is an app your team quietly stops opening.

Got an idea you've been sitting on?

Book a free call. Worst case, you walk away with free advice on what to build first.

Free 20-min idea call · No obligation

Book a Free Call