Engineering
Offline-first is a product decision, not a technical one
Field software fails for a reason that has nothing to do with engineering skill: someone assumed the network.
In short
- Offline-first is a product decision, not a technical one. Retrofitting it means revisiting the data model, conflict semantics, identifier strategy and most of the interface.
- Settle three questions in week one: where identifiers come from, what happens when two people change the same record, and how a user knows their work is safe.
- Client-generated UUIDs at creation time cost nothing on day one and remove an entire class of reconciliation problems that server-assigned IDs create.
- Queue operations rather than end states, with idempotency keys on each, so a series of offline edits replays in order and produces the same result as if it had been made online.
- The failure mode that matters is not ‘no signal’ but intermittent signal with high latency and partial loss, which a lab simulation will not reproduce.
We have now been called in to rescue several field applications that were, by any reasonable measure, competently built. They failed for the same reason each time. Somewhere early on, someone treated connectivity as a given and offline as an error state, and in a rural service territory, a steel-framed warehouse or a hospital basement, the error state is where the work happens.
That is not a bug to be patched later. Retrofitting offline support means revisiting your data model, your conflict semantics, your identifier strategy and most of your interface. It is one of the most expensive changes to make late and one of the cheapest to make at the start.
Three questions to settle in week one¶
Where does an identifier come from?¶
If the server assigns IDs, a device cannot create a record offline without inventing a temporary one and reconciling it later, which leaks into every relationship, every URL and every log line. Client-generated identifiers at creation time cost nothing on day one and remove an entire class of problems. This is the property RFC 9562 exists to provide: no centralized authority is required to administer UUIDs, and generation can be fully automated on demand. Reach for UUIDv7 rather than v4 where you can, because the RFC is explicit that non-time-ordered versions have poor database-index locality, and a field application writing thousands of rows per shift will feel that.
What happens when two people change the same thing?¶
Last-write-wins is a decision to silently discard someone’s work. Sometimes that is acceptable; usually the business has a real answer: the supervisor’s edit wins, or the later timestamp wins, or the record splits and a human decides. Ask the business, because it is a business rule, not a technical default.
How does a user know their work is safe?¶
This is the one that determines adoption. A crew that isn’t sure whether their inspection saved will photograph the screen as a backup, and then keep using paper as well. Sync state has to be visible, comprehensible and honest: what is on the device, what has reached the server, what failed and what they should do about it.
The architecture that follows¶
Local-first means the device’s database is the primary one for the duration of the shift. The application reads and writes locally, always, and synchronization is a background process that never blocks the interface. An outbound queue holds operations rather than end states, so a series of edits made offline replays in order and produces the same result as if they had been made online.
- Operations, not snapshots, in the sync queue, so intent survives rather than just the final value.
- Idempotency keys on every operation, because retries are normal and duplicates are unacceptable.
- Bounded local storage with an explicit eviction policy, or devices will fill up in month four.
- Offline map tiles and reference data pre-staged on the morning connection.
- A visible, honest sync indicator with a manual retry that actually does something.
Test it the way it will be used¶
Simulated network conditions in a lab do not reproduce the failure mode that matters, which is not 'no signal' but 'intermittent signal with high latency and partial packet loss', the state where naive retry logic creates duplicates and optimistic interfaces lie.
Put the device in the truck. Drive the territory. Walk into the basement. On one utility engagement, two weeks of ride-alongs before any design work produced the insight that shaped the entire product, and the crews knew we had done it. That is also why they used it.
Sources
- 1.Universally Unique IDentifiers (UUIDs), IETF RFC 9562,
Related reading
- Systems7 min read
EDI 214 in practice: why your ETAs are wrong
The status feed is not a truth feed. Almost every bad ETA we have been asked to fix comes from four failures that are visible in the message itself.
- Delivery2 min read
An estimate is a range, or it’s a bid
Single-number estimates communicate false precision, and everyone involved knows it. Here’s what we give instead.
Next step
Tell us what’s breaking.
Forty-five minutes, no charge, no deck. We’ll tell you what we’d do, what it would likely cost, and whether you should be building this at all.