Samen Steeve
MY SERVICES.
Back to blog
SoftwareMobileField
February 18, 20266 min read

Offline-First with 60% Network SLA: What the Docs Don't Tell You

Developing mobile or web applications for field agents in remote regions (data collectors, network technicians, delivery drivers) requires a fundamentally different mindset when local network availability regularly drops below 60%. Most documentation treats “offline” as a temporary edge-case. In reality, disconnected mode is the default state of the system.

The Anti-Pattern of the Blocking Loader

The classic mistake is designing the application as a standard HTTP client that displays a loading spinner for every action and returns a network timeout error if the API doesn't reply within 10 seconds. In low-connectivity environments, this renders the app completely unusable. The application must read and write instantly to a local database and delegate synchronization to an asynchronous background worker.

The 3 Pillars of Offline-First Architecture

Here are the indispensable components needed to run a resilient offline-first application:

1. Indexed Local Database (SQLite / WatermelonDB)

All lookup data needed by the agent (catalog, client records, blank templates) must be stored locally. We use client-generated Universally Unique Identifiers (UUIDs) to prevent database key collisions when mutations are merged on the central database.

2. The Outbox Mutation Queue

Every user action that modifies state (creating a report, updating a status) does not trigger an API request. Instead, it is serialized and appended to a local outbox_mutations table.

// Structure of a locally stored mutation
interface OutboxMutation {
  id: string; // Local UUID
  actionType: 'CREATE_REPORT' | 'UPDATE_STATUS';
  payload: Record<string, any>;
  createdAt: string; // ISO timestamp
  status: 'PENDING' | 'SYNCING' | 'FAILED';
  retryCount: number;
}

3. Background Sync Worker

A background worker monitors the network connectivity status. As soon as a stable internet connection is detected, it processes mutations in a strict FIFO (First-In, First-Out) sequence and sends them to the API.

Handling Data Synchronization Conflicts

What happens if agent A updates a customer record while offline, while agent B modifies the same record online at the same time?

A simple “Last-Write-Wins” approach risks destroying data silently. A robust solution requires implementing logical entity versioning (Optimistic Concurrency Control):

// Payload dispatched to the API for synchronization
{
  "client_id": "uuid-1234",
  "version": 4, // The version read locally by the client before editing
  "changes": {
    "phone": "+33614093987"
  }
}

// If the version in the central database has bumped to 5 in the meantime,
// the API returns a 409 (Conflict) HTTP status.
// The client app must then pull version 5 and prompt the user to merge
// or apply an automated business-rule override.

The Takeaway

Offline-first is not a cosmetic feature; it is a major system design decision. It requires robust local storage, decentralized ID generation, idempotent action queues, and active sync conflict resolution. It is the only way to build a reliable user experience when the network is unstable.

Planning a cloud migration?

Let's build a redundant hybrid cloud infrastructure suited for real-world field constraints.

Start a project