Most offline-first failures we've seen come from treating connectivity as a single bit — on or off. In the field, it is a spectrum: high-latency, half-failed, partial, lossy. A useful offline-first design accepts that the network is a continuum, not a switch.
Local-first storage is the foundation. Every write that matters lands on durable local storage before anything else happens, with a clear identifier, a wall-clock timestamp, and an actor. Sync is a separate process that can fail, retry, and resume without the user noticing.
Conflict resolution is where many designs break down. We default to deterministic, server-side resolution — the client never has to make a judgment call. Where the conflict is genuinely ambiguous, we surface it explicitly rather than letting last-write-win silently overwrite a colleague's work.
The result is a system where field teams stop thinking about connectivity. They open the app, do the work, and the platform makes the network problem invisible.
