When we started building Sarathi, our motorcycle road trip companion app, the first architecture question we had to answer wasn't about maps or routing or weather data. It was simpler, and harder: what happens when the user has no internet?

For a consumer app targeting adventure motorcyclists riding through the Spiti Valley, the Western Ghats, or rural Maharashtra, this isn't an edge case. It's the primary use case. The app is most needed precisely when connectivity is worst.

The answer to that question — what happens offline — determines almost everything about how a mobile application is built. Data model. Sync strategy. Conflict resolution. Local storage architecture. API design. All of it flows from that one decision.

"Offline-first is not a feature you add at the end. It's a constraint that shapes the architecture from the first line of code."

What Offline-First Actually Means

There's a common misunderstanding about what offline-first means in practice. Many teams interpret it as "cache some data so the app doesn't crash when there's no connection." This produces what we call offline-tolerant apps — apps that degrade gracefully when offline but fundamentally assume connectivity as their normal operating state.

Offline-first is the opposite assumption. The app is designed to work fully and correctly with no connection, and connectivity is treated as an enhancement — a way to sync state and fetch updates — rather than a prerequisite for function.

The difference sounds subtle. The architectural implications are not.

The Four Decisions That Can't Be Retrofitted

01
The local data model
An offline-first app needs a complete, queryable local data store — not a cache of API responses. For Sarathi, this meant building the full route, waypoint, and trip data model in SQLite locally, with the server model designed to sync from it rather than the other way around. If you start with a server-first data model and try to retrofit local storage, you end up with a partial, inconsistent local state that's impossible to reason about.
02
Conflict resolution strategy
When a user edits a route offline on their phone while another device has synced a different version, which version wins? Last-write-wins is simple but wrong for most cases. Operational transformation is correct but complex. Vector clocks sit somewhere in between. You cannot pick this strategy after the fact — it determines how every write operation in the application is structured. We chose a merge strategy based on operational timestamps with user-visible conflict prompts for cases where automatic resolution would lose data.
03
Sync queue architecture
Every write that happens offline needs to be queued, ordered, deduplicated, and eventually applied to the server — in the right sequence, without losing operations if the app is killed mid-sync. This requires a persistent, ordered operation queue that survives app restarts. It cannot be an afterthought. The queue is as critical to data integrity as the database itself.
04
Map and asset storage
For Sarathi, offline routing requires offline maps. Offline maps require pre-downloaded tile sets for selected regions, managed storage with user-visible size indicators, and a download manager that handles interrupted downloads gracefully. The storage model for binary assets — map tiles, track recordings, cached weather data — has to be designed alongside the data model, not layered on top of it later.

The Retrofitting Problem

We've spoken to several teams who tried to add offline capability to an existing connected app. Without exception, the experience was the same: they thought it would take two sprints and it took six months, and the result still wasn't reliable.

The reason is that a server-first architecture encodes assumptions about connectivity at every layer. API calls happen synchronously at the point of user action. UI state is derived from server responses. Optimistic updates, where they exist, are tacked on as a UX improvement rather than designed as the primary interaction model. Pulling all of those assumptions out and replacing them is effectively a rewrite of the application logic, not a feature addition.

The Rule

If you're building an application where offline capability matters — field operations, travel, rural use cases, any app that goes where connectivity doesn't — make the offline decision before you write the first endpoint. It's the only decision that can't be changed later without paying the full cost of a rewrite.

What We Got Right and What We'd Do Differently

Making the offline-first decision at the start of Sarathi meant our architecture was harder to build initially but dramatically simpler to reason about as the product grew. Adding new data types — track recordings, weather overlays, POI data — followed a clear pattern because the local-first architecture was already established.

What we'd do differently: we underestimated the complexity of the sync UI. The technical sync logic worked well, but communicating sync state to the user — what's saved locally, what's uploaded, what's pending — required a dedicated design pass that we should have planned for from the start. Offline-first architecture solves the data problem. Communicating that architecture to users is a separate, equally important problem.

Sarathi is currently in development, targeting a launch window aligned with our Spiti Valley group ride in July 2026. If you're building a mobile application with offline requirements and want to talk through architecture decisions, or if you want to follow Sarathi's progress — reach out.