Mobile API Best Practices · Offline-First & Sync
Conflict Resolution
Last-writer-wins, field merges, server rules and CRDTs.
Two devices edit the same record offline; who wins? Choose per data type:
- Last-writer-wins (LWW) — simple; loses data; fine for settings.
- Field-level merge — merge non-overlapping field changes; conflict only on the same field.
- Optimistic concurrency — mutation carries
base_version; server rejects stale edits (409/412) and the client rebases or asks the user. - Domain rules — e.g. inventory decrements are commutative operations, not overwrites.
- CRDTs — data types that merge automatically (counters, sets, text) for collaborative editing (Automerge, Yjs).
Conflict strategies
| Criterion | LWW | Field merge | Version check + rebase | CRDT |
|---|---|---|---|---|
| Data loss | Yes | Only same-field | No (user/rule decides) | No |
| Complexity | Low | Medium | Medium | High |
| Needs user prompt | No | Rarely | Sometimes | No |
| Server role | Pick newest | Merge fields | Authority on versions | Relay/persist ops |
| Best for | Preferences, status | Profiles, forms | Business records | Collaborative docs, lists |
function mergeTask(base: Task, mine: Task, theirs: Task): { merged: Task; conflicts: string[] } {
const merged = { ...theirs };
const conflicts: string[] = [];
for (const f of ["title", "notes", "dueDate", "status"] as const) {
const iChanged = mine[f] !== base[f];
const theyChanged = theirs[f] !== base[f];
if (iChanged && !theyChanged) merged[f] = mine[f];
else if (iChanged && theyChanged && mine[f] !== theirs[f]) conflicts.push(f);
}
return { merged, conflicts };
}
PATCH /v1/tasks/01J9…
If-Match: "v14"
{"status": "done"}
412 Precondition Failed # server is at v15 → client fetches v15, rebases, retries
Common pitfalls
- Device timestamps deciding LWW (skewed clocks).
- One strategy for all data.
- Silently dropping the losing edit.
Key points
- Pick a strategy per data type
- Server-assigned versions, not device clocks
- CRDTs for real collaboration
Further reading: crdt.tech: CRDT resources
Practice questions
When is last-writer-wins acceptable?
Answer
For data where losing a concurrent edit is harmless and rare — e.g. user preferences or a toggle — and when 'last' is decided by the server, not device clocks.
How does a three-way merge decide whether a field conflicts?
Answer
It compares both edited versions with their common base: if only one side changed the field, take it; if both changed it to different values, it's a conflict.
Open in the app to mark lessons complete, take notes and track your progress.