Offline-first is a data model decision, not a caching one
Teams try to add offline support late by bolting on a cache. It fails, because the hard question is not storage - it is what happens when two people changed the same thing.
"Make it work offline" sounds like a storage requirement. It is a conflict-resolution requirement wearing a disguise, and that is why retrofitting it is so painful.
The real question
Two users edit the same record while disconnected. Both reconnect. What is true?
Every answer is a product decision, not a technical one:
- **Last write wins.** Simple, and silently destroys someone's work.
- **Server wins.** Predictable, and makes offline editing pointless.
- **Merge per field.** Often right, and requires field-level change tracking from the start.
- **Ask the user.** Honest, and needs interface design nobody budgeted for.
You cannot pick this after the schema exists. Field-level merging needs per-field timestamps or versions, which is a schema decision made at the beginning.
Model changes, not state
Offline systems that work tend to sync intent rather than rows. "User marked item 42 complete at this time" replays and merges. "Here is my copy of item 42" overwrites.
An append-only log of operations, reconciled on reconnect, is more work up front and dramatically less painful in year two.
Identity has to work offline
Records created offline need identifiers before the server sees them. That means client-generated IDs - UUIDs or similar - not database sequences. Another decision that is trivial at the start and a migration later.
Be honest in the interface
Users forgive a system that says "saved on this device, not yet synced". They do not forgive one that showed a checkmark and then lost the entry. Sync state belongs in the interface, not hidden behind an optimistic tick.
