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
- Validate what can be checked safely on the device.
- Commit the local record change and outbox operation together.
- Select eligible work when the app or background scheduler can run.
- Send identity, operation ID, command and known record version.
- Let the server make current access and business decisions.
- Apply the response atomically to local record and operation state.
- 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
| Identifier | Purpose | Example behaviour |
|---|---|---|
| Record ID | Names the business object across devices and systems | Stable after local creation and server acceptance |
| Operation ID | Names one logical change | Reused on every retry of that change |
| Record version | States which server revision the device knew | Detects stale updates and supports conflict decisions |
| Sync cursor | Marks the last remote change applied | Requests 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
| Result | Likely action | Why |
|---|---|---|
| No response or temporary service failure | Retry with bounded backoff and jitter | The same operation may succeed later |
| Authentication expired | Refresh safely or pause for sign-in | Repeated delivery cannot restore identity by itself |
| Not authorised | Stop and explain the current access decision | Permission must change before the action can succeed |
| Validation rejected | Stop and request corrected input | The same payload will remain invalid |
| Version conflict | Run the defined conflict policy | Blind retry may overwrite newer work |
| Already accepted | Return the recorded outcome | Idempotency 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
- Terminate the app after local commit but before delivery.
- Deliver the same operation more than once.
- Accept the operation but drop the response.
- Change the user's permission while work is pending.
- Edit the record from another device before delivery.
- Return changes out of order and across a cursor boundary.
- Restart during a database or app-schema migration.
- Keep the device offline beyond token and data-expiry periods.
- 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.