Offline-First Architecture: Full Functionality Without Connectivity
Enterprise mobile apps serve people who work in places with unreliable connectivity — construction sites, hospital basements, rural areas, elevator rides before client meetings. An app that shows a spinner when the network drops is useless to the people who need it most.
What does offline-first actually mean?
Offline-first means the app works without a network connection as its default state. Network availability is a bonus that triggers background synchronization — not a prerequisite for basic functionality. Every screen renders from local data. Every user action writes to a local database first, then syncs when connectivity returns.
This requires a local database that’s fast enough for real-time queries, encrypted (it contains CRM data with PII), and structured enough to support the app’s full query patterns without a server roundtrip. Our local database runs AES-256 encryption on every byte via an encrypted SQLite implementation, with the encryption key stored in the platform’s hardware-backed secure storage.
The database is organized across multiple domains — each with clear ownership rules. Server-owned data (CRM records, call data) is treated as a cache with the server as authority. Client-originated data (local settings, analytics) uses last-write-wins. Simple conflict resolution by design, because the CRM itself is the source of truth.
How are encryption and migration handled?
Every byte of the local database is encrypted at rest. The encryption is transparent to the application layer — SQL queries work identically on encrypted and unencrypted databases. The encryption key is generated from the platform’s cryptographically secure random number generator and stored in hardware-backed secure storage.
This means the encrypted database is tied to the device and the app installation. A database file extracted from the device is unrecoverable without the key. If the app is uninstalled, the key is deleted and any persisted database file is permanently unreadable. For PII on a mobile device, this is the correct behavior.
We designed the migration path to handle the transition from unencrypted development databases to encrypted production databases transparently on app startup — checking the current state, performing a one-time encrypted export if needed, and verifying the migration before swapping files. The migration is idempotent: safe to re-run if interrupted by a force-quit, a crash, or low storage. Why no secret ever ships in the binary itself: mobile security without device secrets.
How does the database stay bounded and fresh?
An offline database accumulates data over time. Without pruning, it grows indefinitely — slowing queries, consuming device storage, and retaining PII longer than necessary.
We define retention policies per data category, each with an appropriate window. Pruning runs non-blocking at app startup so users never wait for cleanup. Each category prunes independently in parallel, so a failure in one doesn’t block the others. The pruning uses indexed timestamp columns for efficient execution.
The key distinction: pruning applies to local cache data, not to source-of-truth business records. The CRM data, which lives in the remote system, is never deleted by our application — that’s the Zero-Delete principle at work. The local database is a cache that’s kept fresh, bounded, and encrypted. The remote system is the permanent record. The pruning mechanics live in the offline-first architecture.
Note: Offline-first doesn’t require complex conflict resolution for most enterprise apps. If your app reads and writes to an external system of record, that system is the authority. Local state is a cache that syncs, not a peer that merges.
App Development
Focused applications, fixed scope, handed over clean — code, docs, infra all yours.
See how engagements workTalk2CRM — Voice-to-CRM Mobile App
Mobile app that turns sales calls into CRM records. AI extracts contacts, deal values, and commitments from the call so reps stop typing afterward — with two-layer PII redaction before anything is processed. In beta now.
Want to see more patterns from production?
See the past work where these patterns run in production, or browse the rest of the library.