Offline-First Architecture Interview Questions

DATA › Offline

What does making the local Room database the single source of truth actually buy you architecturally, compared to a simpler design where the ViewModel decides whether to show cached or network data?

What a strong answer covers: With Room as the single source of truth, the UI just observes one Flow and never has to reason about which source it's looking at, network results get written into Room and the UI updates as a side effect of that write, so there's one code path for 'data changed' instead of two (network-arrived vs cache-loaded) that the ViewModel would otherwise have to reconcile and keep in sync. The ViewModel-decides approach tends to grow subtle bugs where the UI shows stale cached data after a successful network fetch because the ViewModel forgot to merge the two paths correctly, or double-renders during the handoff.

How do you handle a queued offline write that depends on another queued write that hasn't synced yet, like adding a comment to a post that itself hasn't reached the server?

What a strong answer covers: The sync worker needs to process the queue in dependency order, not just FIFO by timestamp, typically by giving each queued operation a reference to the client-generated ID of anything it depends on and having the worker defer an operation until its dependency has a confirmed server ID; the local UI can still show the comment optimistically against the client-side temp ID. The trap is naively retrying the dependent write first, getting a foreign-key rejection from the server, and either dropping the write or retrying forever without ever fixing the ordering.

Design question: a user comes back online after two weeks offline with thousands of pending queued writes. Walk me through how you'd replay that queue without overwhelming the server, and how you'd surface partial or failed sync progress to the user.

What a strong answer covers: You'd batch and throttle the replay, WorkManager naturally serializes a single sync worker so you're not firing thousands of parallel requests, and you'd cap batch size per request where the API supports bulk endpoints, backing off on 429/5xx rather than hammering the server. For visibility, each queued item should carry its own status (pending/syncing/failed/synced) that the UI can reflect, ideally as a lightweight sync-progress indicator or a per-item error state that lets the user retry or discard the individual failures rather than presenting sync as one opaque all-or-nothing operation.

Back to Offline-First Architecture