Mobile data synchronisation guide

How offline mobile app synchronisation works

Synchronisation turns durable local intent into a confirmed server outcome. Stable identifiers, record versions, safe retry and explicit conflict rules make that transition reliable.

The short answer

Offline mobile synchronisation starts by saving approved user work locally with a stable operation ID. When communication is possible, the app sends the operation and its known record version to the server. The server authenticates, authorises, validates, protects against duplicates and either accepts the change, rejects it or reports a conflict.

The app writes that authoritative result back to local state and shows the user whether work is pending, confirmed, failed or needs review. The process is a distributed business workflow, not a blind database copy.

01

The synchronisation cycle has seven durable steps

Local actionOutboxDelivery attemptServer decisionLocal reconciliation
  1. Validate what can be checked safely on the device.
  2. Commit the local record change and outbox operation together.
  3. Select eligible work when the app or background scheduler can run.
  4. Send identity, operation ID, command and known record version.
  5. Let the server make current access and business decisions.
  6. Apply the response atomically to local record and operation state.
  7. Expose the new state to the interface and operational telemetry.

If the process stops after any step, durable state should let it resume without inventing a new operation.

02

Use different identifiers for records, operations and sync position

IdentifierPurposeExample behaviour
Record IDNames the business object across devices and systemsStable after local creation and server acceptance
Operation IDNames one logical changeReused on every retry of that change
Record versionStates which server revision the device knewDetects stale updates and supports conflict decisions
Sync cursorMarks the last remote change appliedRequests only changes after a server-issued checkpoint

Do not rely on device timestamps alone for ordering or conflict authority. Clocks can differ and may change. Use server-issued versions, sequences or opaque cursors where the backend can provide them.

03

Use an outbox to protect local intent

The outbox is a durable list of operations that still need a remote decision. Store the operation in the same local transaction as the user-visible change where the storage technology supports it.

  • operation ID and type;
  • target record and known version;
  • minimum command payload;
  • identity or account context without copying secrets;
  • creation order and dependency where order matters;
  • attempt count and next eligible attempt;
  • current state and last classified failure; and
  • retention or escalation rule.

Files may need a separate transfer state because a large upload and its business command can fail independently. Link them through stable identifiers instead of hiding both inside one opaque retry.

04

Retry by failure class, not by hope

ResultLikely actionWhy
No response or temporary service failureRetry with bounded backoff and jitterThe same operation may succeed later
Authentication expiredRefresh safely or pause for sign-inRepeated delivery cannot restore identity by itself
Not authorisedStop and explain the current access decisionPermission must change before the action can succeed
Validation rejectedStop and request corrected inputThe same payload will remain invalid
Version conflictRun the defined conflict policyBlind retry may overwrite newer work
Already acceptedReturn the recorded outcomeIdempotency converts uncertainty into a known result

A timeout means the outcome is unknown, not necessarily failed. Query or retry by operation ID so the server can return the earlier result safely.

05

Conflict resolution belongs to the business model

Reject

Optimistic concurrency

Return the current server record when the known version is stale.

Merge

Independent change

Combine only fields or events proven not to compete.

Append

Event history

Keep separate observations, scans or evidence as immutable entries.

Resolve

Human decision

Create an owned case when consequence or ambiguity is material.

Document whether deletion is a state, a tombstone or a permanent event. If a server deletes a record while a device is offline, the device needs a way to learn that fact without recreating the record accidentally.

06

Tell the user what has happened, not what the network might do

  • show when displayed data was last confirmed and whether it may be stale;
  • distinguish “saved on this device” from “accepted by the business”;
  • show the number and age of important pending actions;
  • let users inspect failures and correct recoverable input;
  • avoid success language before server confirmation where consequence is material;
  • preserve work across process termination and device restart; and
  • make manual synchronisation useful without requiring it for every journey.

A field worker should not need to understand queues or HTTP. The interface should translate technical state into the business meaning of pending, confirmed or needing attention.

07

Test the gaps between every step

  1. Terminate the app after local commit but before delivery.
  2. Deliver the same operation more than once.
  3. Accept the operation but drop the response.
  4. Change the user's permission while work is pending.
  5. Edit the record from another device before delivery.
  6. Return changes out of order and across a cursor boundary.
  7. Restart during a database or app-schema migration.
  8. Keep the device offline beyond token and data-expiry periods.
  9. Recover from a terminal failure without losing the audit trail.

Monitor queue depth, oldest pending age, retry distribution, conflicts, terminal failures and time from local creation to server confirmation. Link these signals to the mobile API and integration boundary.

Start with the offline-first product guide, or use the Flutter architecture guide for a framework-specific implementation.

Sources

Primary references

Questions

Frequently asked questions

How does offline mobile app synchronisation work?

The app reads from local state, records permitted changes as durable operations, sends them when the service is reachable, applies authoritative server responses and updates the user-visible status. Versions and conflict rules reconcile concurrent changes.

How do you prevent duplicate offline submissions?

Give each logical operation a stable client-generated identifier or idempotency key. The server records the first accepted outcome and returns that same outcome when the operation is retried.

What happens when two devices edit the same record offline?

The server compares record versions and applies a defined policy: reject stale changes, merge independent fields, append immutable events or create a case for human resolution.

Should the app retry every failed request?

No. Retry temporary failures such as network interruption or some unavailable-service responses. Stop and surface validation, authentication, authorisation and business-rule failures until the cause changes.

Does synchronisation need to run in the background?

Not always. Some products can synchronise when opened or when the user requests it. If background work matters, it must use platform-supported scheduling and still tolerate delayed or interrupted execution.

Design the sync protocol

Bring one offline write, its business consequence, record ownership and expected conflict.

LCR can model the operation lifecycle and validate it across the app, API and systems of record.