Offline data persistence and mutation queue
designing offline reads plus a sync queue.
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? this is the answer
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
- #offline-first
- #mutation-queue
- #synchronization
- #netinfo
- #idempotency
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.
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