Offline-First Mobile Sync Conflict Resolution Guide

Design a robust offline-first sync strategy for mobile apps, including conflict handling, queues, retries, and user-facing recovery states.

Prompt Template

You are a senior mobile architect with deep experience in offline-first apps, sync engines, and local-first UX. Help me design conflict resolution for this app.

**App type:** [field service app / notes app / CRM / inventory app / healthcare app / other]
**Platforms:** [iOS / Android / React Native / Flutter / web]
**Backend:** [REST / GraphQL / Firebase / Supabase / custom]
**Local storage:** [SQLite / Core Data / Realm / IndexedDB / other]
**Data entities that sync:** [list entities and relationships]
**Offline duration expected:** [minutes / hours / days]
**Users editing the same records:** [rare / common / high collaboration]
**Business risk of bad merge:** [low / medium / high, explain]
**Current sync pain:** [duplicates, overwrites, stale records, failed uploads, user confusion]

Produce a technical design with:
1. **Sync model recommendation** — last-write-wins, server-authoritative, CRDT, field-level merge, operational transform, or manual review, with rationale.
2. **Entity-by-entity conflict matrix** — conflict type, detection rule, merge strategy, and user-visible behavior.
3. **Local queue design** — pending operations schema, idempotency keys, retry/backoff rules, and ordering guarantees.
4. **API contract changes** — version fields, updatedAt/source clocks, ETags, conflict response format, tombstones, and pagination rules.
5. **User experience states** — offline banner, pending changes, conflict review screen, failed sync recovery, and destructive-change warnings.
6. **Testing plan** — unit tests, integration scenarios, clock skew tests, network flapping, multi-device edits, and migration tests.
7. **Observability** — metrics, logs, dashboards, and alert thresholds for sync health.
8. **Rollout plan** — feature flags, backfill/migration steps, staged release, and rollback strategy.

Include pseudocode for the sync loop and conflict detection.

Example Output

Recommendation

For a field service inspection app, use **server-authoritative sync with field-level merge** for low-risk fields and **manual conflict review** for signed inspection results.

Conflict Matrix

| Entity | Conflict | Detection | Resolution | UX |

|---|---|---|---|---|

| WorkOrder | status changed on two devices | serverVersion mismatch | server wins unless local status is `completed` | show “Status updated elsewhere” toast |

| InspectionAnswer | same answer edited twice | field hash mismatch | manual review | conflict sheet with both values |

| PhotoAttachment | duplicate upload | idempotencyKey match | de-dupe on server | no user interruption |

Local Queue Schema

type PendingOperation = {

id: string;

entityType: 'workOrder' | 'inspectionAnswer' | 'photo';

entityId: string;

operation: 'create' | 'update' | 'delete';

baseVersion: number;

idempotencyKey: string;

payload: unknown;

createdAt: string;

attempts: number;

};

Sync Loop Pseudocode

while (online) {

const op = queue.nextReady();

const res = await api.applyOperation(op);

if (res.status === 409) storeConflict(op, res.serverRecord);

else if (res.ok) queue.markComplete(op.id, res.newVersion);

else queue.scheduleRetry(op.id, exponentialBackoff(op.attempts));

}

Observability

- Conflict rate > 3% of update operations for 15 minutes → warn

- Queue age p95 > 10 minutes while online → alert

- Duplicate upload rejection rate by app version → release health dashboard

Tips for Best Results

  • 💡Do not default to last-write-wins for high-risk data; it is simple until it silently loses important work.
  • 💡Use idempotency keys for every queued mutation so retries are safe.
  • 💡Design the conflict UI before finalizing the data model — UX constraints should shape merge strategy.
  • 💡Test with clock skew and airplane-mode toggling; happy-path Wi-Fi tests miss most real sync bugs.