# Design Mobile Email: Gmail-Style Sync and Search

Source: https://www.techinterview.org/post/3233475020/design-mobile-email-gmail-sync-search/
Updated: 2026-07-26 · techinterview.org

"Design Gmail mobile" sounds boring until you start. Then you realize: 1B+ users, threads with 100+ messages, multi-megabyte attachments, search across years of mail, push that wakes the app within seconds of arrival, offline composition, and labels/folders that sync across devices. The interview tests whether you understand layered sync, search index design, and [conflict resolution](/post/3233460997/system-design-collaborative-editing/) at scale.

## Functional requirements

- List inbox and folders/labels — Gmail uses labels rather than folders, so one message can carry several at once; interviewers want to see the many-to-many message-label mapping, not a single-parent folder tree.

- Read messages with threading — the conversation view groups related messages, so be ready to talk through collapsing quoted replies and lazy-loading threads that run past 100 messages.

- Compose, reply, forward — draft autosave and quoting the original body are the meat here; reply versus reply-all and whether forwards carry attachments along are common follow-ups.

- Search with sub-second results — scope it early as two tiers: instant local search over cached mail and a slower server search across years of history, plus how you merge the two result sets.

- Push notifications on new mail — the bar is waking the app within seconds of arrival, so expect questions on delivery guarantees and what happens when the device is offline at the moment the mail lands.

- Offline access to recent mail — decide which slice of mail is cached and how actions taken offline (read, archive, send) queue locally and reconcile on reconnect.

- Multi-account support — each account keeps its own sync state and credentials; a strong answer points out that switching should feel instant because the data is already on-device.

## Architecture

Three modules: **local store**, **sync engine**, **push integration**.

## Local store

SQLite. Tables for messages, threads, labels, attachments, drafts. FTS5 for full-text search. The app caches recent messages locally; older messages are server-only.

Storage budget: typically last 30 days of mail, plus all starred or labeled messages, plus full thread for any thread with a recent message.

## Sync

Gmail uses a History ID model. Each mailbox has a monotonically increasing history ID. Client tracks last-seen ID; on sync, requests "all changes since X." Server returns adds, modifications, deletions.

Two-way sync: client-side actions (mark as read, archive) generate operations queued for upload. On reconnect, ops are applied to the server, history advances, and sync continues.

## Push notifications

Server pushes a "data available" notification on new mail. Client wakes briefly, fetches the new message, and renders the notification with subject and snippet. Privacy mode: notification body is generic, content is fetched only when app opens.

## Search

Two layers:

- **Local FTS:** recent messages, instant results

- **Server search:** full mailbox, slower (200–1000ms), broader scope

UI shows local results first, then merges server results when they arrive.

## Offline composition

Drafts saved to local SQLite with status `pending`. On send tap, the message moves to outbox. Background uploader (URLSession or WorkManager) attempts delivery; on success, transitions to `sent`.

Attachment uploads happen in chunks. Resumable across app restarts.

## Threading

Threads are server-computed by Gmail (RFC 822 headers + Subject + In-Reply-To). The client just renders the pre-grouped thread.

## Multi-account

Each account has its own sync state and local DB tables. Common code path; separate credentials. Switching accounts is instant because everything is local.

## Battery and data

- Sync is push-driven; no polling

- Attachments downloaded on tap, not eagerly

- Background sync is rate-limited by OS budget

## Frequently Asked Questions

### How does Gmail handle a deleted email that arrives via push?

Push tells the client "history changed." Client fetches the change, sees a delete, removes the message locally. The notification is suppressed.

### How does threading handle replies from non-Gmail clients?

RFC 822 References and In-Reply-To headers. Most modern clients respect these; older ones do not, and threading falls back to subject + sender heuristics.

### Why does email search sometimes miss recent messages?

Local FTS indexing happens asynchronously. Very recent messages (last few seconds) may not yet be in the index.
