Skip to content
tezvyn:
Menu

Offline data persistence and mutation queue

Source: interviewHardHow cards are made

Summary

designing offline reads plus a sync queue.

Key points

persist reads to local storage, store mutations in a durable queue with client ids and status, drain and reconcile on reconnect via NetInfo.

What's really being asked

Whether you can architect the harder write path of offline support, not just read caching, including durability, ordering, id reconciliation, and idempotency.

The full answer

For reads, persist fetched data to AsyncStorage for small state or SQLite/WatermelonDB for large relational data, hydrating the store on launch so screens render without a network. For writes, maintain a durable mutation queue persisted to disk so it survives app restarts; each entry has a client-generated id, the operation type, payload, and a status. When a mutation happens offline, append it and update the UI optimistically. A NetInfo listener detects reconnection and a sync worker drains the queue in FIFO order, replacing temporary ids with server-assigned ones in dependent records, retrying transient failures with backoff, and removing succeeded entries. Mutations should be idempotent or carry a request id so a replay after an ambiguous failure does not duplicate data.

The mistakes people make

Caching only GET responses, holding the queue purely in memory so it vanishes on restart, ignoring ordering between dependent mutations, or not reconciling temporary client ids with server ids. Skipping idempotency invites duplicate items when a request succeeds but the response is lost.

What usually comes next

How do you guarantee ordering when one mutation depends on another's server id? How do you make replays idempotent? How do you resolve conflicts if the server changed too? How does WatermelonDB's sync help?

A concrete example

Offline, the user creates a task. The app stores it locally with id tmp-9, status pending, and shows it. On reconnect, the worker POSTs the task, receives server id 512, rewrites tmp-9 to 512 everywhere it is referenced, and clears the queue entry. If the POST times out but actually succeeded, the carried request id lets the server dedupe, so retrying does not create a second task.

Interview question

Why should queued offline mutations carry a client-generated request id when they are later replayed to the server?

  • a.Because the server cannot otherwise authenticate offline requests
  • b.So the server can deduplicate replays, preventing duplicates after an ambiguous failureCorrect
  • c.To let AsyncStorage compress the payload more efficiently
  • d.So the queue can be sorted alphabetically before syncing
Why?

If a request succeeds but its response is lost, replaying it could create duplicates; a request id lets the server recognize and dedupe the retry. Ids are not for sorting, auth, or compression, so those options are incorrect.

Just read this? Test yourself on what you have been reading.

Read the original → dev.to

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.

See open roles