From sync conflicts to local storage strategies, here's how we approach offline-first architecture in mobile apps used in low-connectivity environments.
In India, 4G coverage is widespread but reliability isn't. Elevators, basements, rural areas, and high-traffic events all create connectivity black holes. If your app stops working the moment the signal drops, you're failing a significant portion of your users.
Offline-first isn't a feature — it's an architectural philosophy. It means the app works fully offline, and connectivity is treated as an enhancement (for sync) rather than a requirement.
The first decision is where to store data locally. Your options in mobile:
SQLite (via Drift/Room) — Best for relational data with complex queries. We use this for apps with inventory management, scheduling, or any data with relationships.
Hive (Flutter) / MMKV (React Native) — Best for key-value and simple object storage. Extremely fast reads. We use this for user preferences, cached API responses, and session data.
Realm — Great for complex object graphs with automatic sync via Atlas Device Sync. Higher setup cost but powerful for enterprise use cases.
For most apps, SQLite + a dedicated cache layer (Hive/MMKV) covers everything you need.
Syncing local changes to the server is where offline-first gets genuinely hard. The core challenge: what happens when the same record is modified offline on two devices?
Our Sync Architecture:
1. Operation Queue — Every mutation (create, update, delete) is written to a local queue before being applied locally. 2. Optimistic Updates — The UI updates immediately using local data. No loading spinners for writes. 3. Background Sync — A background service drains the queue when connectivity is available. 4. Conflict Resolution — We use Last-Write-Wins (LWW) with server timestamps for most cases. For collaborative features, we implement field-level merging. 5. Retry with Backoff — Failed sync operations retry with exponential backoff. After 5 failures, we surface an error to the user.
After building multiple offline-first apps, here are the mistakes we see most often:
1. Syncing too much data — Don't sync the entire database on every connection. Use delta sync — only sync records changed since the last sync timestamp.
2. Ignoring storage limits — Mobile devices have limited storage. Implement data expiry and cleanup for cached records older than N days.
3. No conflict UI — Sometimes automatic conflict resolution isn't enough. Build a way to surface conflicts to users for critical data (financial records, medical data).
4. Testing only online — Use airplane mode and throttled connections in testing. Bugs in sync code only appear under real conditions.
5. Not handling partial sync failures — A sync operation that fails halfway can leave data in an inconsistent state. Use transactions for all sync writes.
For Gram Parivartan — our CSR app used in rural India — offline-first architecture was the entire product. Field workers in villages with no connectivity could collect data all day and sync when they reached town. The app handled weeks of offline operation without issues.
Offline-first is harder to build, but the user experience improvement in real-world conditions is transformative. If your app will be used in India at scale, it's not optional.
We'd love to hear about your project and see how we can help.
Start a Conversation →