The idea, explained

Offline-first design has two separate jobs. First, the application must remain usable without a network. Static resources such as pages, scripts and images can be cached locally. Working data can also be kept in a local database. Second, user changes must survive until the server accepts them. A common pattern is an outbox: each local action becomes a durable queued operation with a unique identifier, creation time and the version of the record the user saw.

When connectivity returns, a synchronization worker sends queued operations. Retries are necessary because the connection may fail again, but retries can duplicate a request. The server therefore needs idempotency: processing the same operation identifier twice must have the same effect as processing it once. The client should remove an item from the outbox only after receiving a durable acknowledgement.

Synchronization creates a harder problem when the server changed during the offline period. Version numbers can detect this. If a client edits version 4 while the server has reached version 6, the system knows the update is stale. Optimistic concurrency rejects the stale update and returns the current record so the user or client can retry. Automatic merge can be safe for some structures: two sets may be combined without duplicates, while independent fields may be preserved. It is dangerous for scalar decisions such as a delivery status, approval or account balance because choosing one value automatically can hide a real disagreement.

A reliable design defines conflict rules by data type and business consequence. Low-risk additive notes may merge automatically. High-impact fields may require human review. The system should preserve an audit trail, expose synchronization status and avoid telling users that work is saved when it exists only in volatile memory.

Follow a worked example.

Consider a field logistics app with inventory record ITEM-7 at server version 12 and quantity 40. Device A goes offline and records a shipment of 6 units. Its outbox stores operation OP-301: subtract 6 from ITEM-7, based on version 12. While A is offline, Device B records a shipment of 5 units, so the server quantity becomes 35 at version 13.

Step 1: Device A reconnects and submits OP-301. Step 2: the server sees that version 12 is stale because the current version is 13. It must not simply replace quantity 35 with A’s locally calculated quantity 34; that would erase B’s shipment. Step 3: because the operation is expressed as a change rather than a replacement, the server can apply 35 − 6 = 29, create version 14 and acknowledge OP-301. Step 4: if A retries OP-301 after losing the acknowledgement, the server recognizes the same operation identifier and returns the prior result instead of subtracting 6 again.

The final quantity is 29, reflecting both shipments: 40 − 5 − 6. If the field represented an approval status rather than an additive quantity, the safer rule might be to stop and request review instead of merging automatically.

Where people get stuck

A common misconception is that caching makes an application offline-first. Caching can display old screens, but it does not guarantee that new work is durably queued, retried once, reconciled with newer server state or explained to the user. Another pitfall is using “last write wins” for every conflict. That rule is simple, but clock differences and delayed connections can cause a legitimate update to disappear. Choose conflict behavior from the meaning of the data, not merely from implementation convenience.

Now try it yourself.

Pause before opening each answer. Explain your reasoning in your own words.

1. Check the core idea

Two offline users edit the same delivery record. One changes the address and the other changes the delivery status. What should the synchronization system check before automatically merging both updates?

Reveal the answer & reasoning

It should compare the record versions, identify exactly which fields changed, and apply field-specific business rules. The address and status are different fields, so a structural merge may be technically possible, but the system must still ask whether the changes are logically compatible—for example, whether changing an address after dispatch is allowed. It should also verify unique operation identifiers so retries do not repeat side effects, preserve an audit trail, and route any high-impact or incompatible combination for human review. Different fields do not automatically mean a conflict is harmless.

Why this was added

The library covers caching, retries and eventual consistency separately, but not the end-to-end offline-first pattern that combines durable local work, synchronization and domain-aware conflict resolution.