Designing offline-first mobile apps that never lose user work

Cellular networks drop in elevators, subways, and warehouses. How we architect local SQLite state and idempotent Go sync endpoints for iOS and Android.

Sunlit senior software engineering desk with mobile architecture schematics and device frames

Why "spinner-first" apps fail in the field

Many mobile applications are built as thin wrappers around REST endpoints: every screen transition fires a network request and blocks the user with a loading indicator. In an office on gigabit Wi-Fi, this appears to work. In an elevator, on a commuter train, or inside a hospital corridor, the app stalls or discards what the user just typed.

Local SQLite as the single source of UI truth

At Sisnex, our default architecture for business-critical mobile apps treats the on-device database (SQLite via SwiftData/GRDB on iOS, Room on Android, or Drift on Flutter) as the primary source of truth for the user interface:

  1. Reads never touch the network directly: Screens observe local database queries reactively. Opening the app renders cached data in under 16 milliseconds—even in airplane mode.
  2. Writes commit locally first: When a user submits a form or updates an item, we write the mutation to an on-device outbox queue with a client-generated UUID and update the local state immediately.
  3. Deterministic background reconciliation: A background worker drains the outbox whenever connectivity returns, sending idempotent requests to our Go API.

Idempotency keys on the backend

Network retries are inevitable on cellular connections: a client may send a POST request, the server commits the transaction, and the response packet is lost when the user enters a tunnel. Without idempotency, the client retries and creates duplicate records or double charges.

Every mutating endpoint we build in Go accepts an Idempotency-Key header tied to the client's outbox entry. If the server sees the same key twice, it returns the stored result without re-executing the side effect.

The result is software that feels calm, instant, and trustworthy regardless of signal bars.

architectureiosandroidbackend

Related articles

  1. Native Swift & Kotlin vs. Flutter: how we advise clients in 2026

    A practical decision framework for choosing between true native iOS/Android codebases and a unified Flutter application based on hardware depth, longevity, and team budget.

    2 min read

  2. Why we build mobile software with a senior-only studio model

    Most mobile projects fail in the handoffs between account managers, junior contractors, and disconnected backend teams. Here is how Sisnex structures engagements differently.

    2 min read