Course Content
Mobile System Design Interview
11 sections · 23 lessons
The framework: client architecture, data flow and the closing fifteen minutes
Steps 3 and 4 are the two ten-minute blocks in the middle of the round, and they are where the marks are. Step 3 is the diagram you draw in every mobile system design interview: learn one shape, then change the labels for each problem. Step 4 says how a change moves through that shape, and it is where a design is either coherent or a collection of boxes.
Then the last fifteen minutes — the deep dive, the constraint sweep and the edge cases — decide whether a competent answer becomes a strong one. This lesson covers all four.
Step 3: three layers
Presentation. Screens and the objects that hold their state. Its rule: it knows nothing about the network, the database, or where data came from. It asks for data and renders what it gets.
Domain. The application's actual rules — validation, what a "conflict" means, when a draft becomes a message. On small features this layer is thin or absent, and saying so is better than inventing ceremony for it.
Data. The repository, plus the two things underneath it: a local store and a remote data source. The repository is the important box.
The repository, and why it is the answer to most questions
A repository exposes data to the layers above it and hides where that data came from. It is the single source of truth: one place that decides what "the current feed" is, so two screens showing the same post cannot disagree.
The rule that makes offline work is a property of this box: the repository reads from the local store and writes network results into it. Callers get local data, always. The network is a background process that keeps local data fresh.
Naming, and not arguing about it
Every platform has its own name for the presentation pattern. Say which one you would use, in one sentence, and move on: "I'd use whichever unidirectional presentation pattern the team already uses — the architecture below the presentation layer is the same either way."
Spending three minutes defending one pattern over another is a poor use of the round. The interviewer is checking that layers exist and are respected, not adjudicating a naming dispute.
Step 4: data flow and state
Layers say what exists. Data flow says how a change moves through them.
Unidirectional data flow
Data moves in one direction round a loop: an event goes down, a change is written, new state comes back up, the screen re-renders.
user taps "like" → screen emits an intent → state holder calls repository.like(postId) → repository writes to local store: liked = true, pending = true → local store emits a change → repository's stream emits new state → screen re-renders with the heart filled ... separately, the outbox drains to the network, and clears `pending` (or reverts on permanent failure)Nothing skips a step and nothing flows backwards. That property is what makes the app debuggable: any wrong pixel is traceable to a write in the local store.
The naive alternative — the screen calls the network, gets a response, and updates itself directly — produces two problems immediately. Two screens showing the same post disagree, because each has its own copy. And the change is lost when the process is killed, because it was never written anywhere.
The rule that makes offline work
Say this out loud in the interview. It is short, it is the correct answer to a large class of follow-up questions, and it tells the interviewer that the architecture you drew was not decoration.
Where state lives, in four tiers
| Tier | Lifetime | Examples |
|---|---|---|
| Ephemeral UI state | Until the screen closes | Scroll offset, text being typed, whether a sheet is open |
| Screen state | Survives rotation and short backgrounding | The list being displayed, the selected filter |
| Persisted app state | Survives process death | Feed rows, messages, drafts, the outbox |
| Server state | Shared across devices | Everything the account owns |
The tier that gets forgotten is the third. A user filling in a booking form, backgrounded while they check an email, returns to an empty form because the draft lived in memory. Client architecture for a multi-step flow designs around exactly that.
Process death, and the honest way to talk about it
Process death is not an edge case — it is routine. The operating system reclaims backgrounded apps under memory pressure many times a day. When the user returns, the app is relaunched from scratch and must reconstruct the screen they were on.
What must survive: where they were, what they had typed, and anything they had done that has not reached the server. What need not: caches, in-flight requests, and anything derivable.
Steps 5–7: depth, constraints, and edge cases
With the architecture and the data flow on the board, you are at about minute thirty. The last fifteen minutes decide whether a competent answer becomes a strong one.
Step 5: the deep dive
Around minute thirty the interviewer picks a component and asks for detail. If they do not pick, offer two and let them choose: "I could go deep on the sync engine or on scroll performance — which is more useful?"
Going deep means four things, and shallow answers usually miss the last two:
- The data structures. Actual tables, actual fields, actual indexes.
- The algorithm. Stepped through with a concrete case, not described in the abstract.
- The failure cases. What happens when this component's assumptions are violated.
- The numbers. How big, how often, how long, how much memory.
If you have a choice, pick the component with an interesting offline or concurrency story. A sync engine, an outbox, or an update-coalescing pipeline gives you more to say than a list-rendering path — unless the interviewer has signalled they care about rendering, in which case they have told you the answer.
Step 6: the six constraints
Cover all six, briefly, out loud. One sentence each is enough, and omitting one is noticed.
| Constraint | The sentence |
|---|---|
| Network | "Reads come from the local store, so the app works with no network; writes queue in the outbox." |
| Battery | "We batch requests and drop to push when backgrounded, because radio wake-ups cost more than payload size." |
| Memory | "Images are downsampled to display size at decode time; the list recycles views." |
| Storage | "The cache has a ceiling of N MB, evicted least-recently-used, and the user can clear it." |
| Background limits | "Sync is a deferred job, so it may not run for hours; nothing time-critical depends on it." |
| Process death | "Screen position, drafts, and the outbox are persisted, so a relaunch restores the user's place." |
Six sentences, roughly ninety seconds. It is the cheapest block of marks in the round.
Step 7: edge cases and the close
Pick two or three that are specific to this problem rather than generic. The strongest ones are usually:
- The first launch with an empty database and no network.
- The very large case: a user with 50,000 items, an account with a two-year backlog.
- Concurrency: the same entity changed on two devices, or by a push while the user is editing it.
- Permissions revoked — notifications, storage, location — after the feature was built assuming them.
Then close in two sentences: what you would build first, and what you would measure to know it works.