iosNudge

Introduction

Chapter 1 of 8 4 min read

What is a mobile system design round?

You design an app or one feature of an app. You talk, draw boxes, and write a few Swift types. You do not write a full program.

The prompt is short and open on purpose:

  • "Design a photo feed like Instagram."
  • "Design a chat app."
  • "Design an offline-first notes app."
  • "Design an image loading library."
  • "Design a screen that tracks a taxi on a live map."

The round is usually 45 to 60 minutes. There is no single right answer. The interviewer wants to see how you think, how you choose, and how you explain your choices.

How it is different from backend design

A backend round asks: "How do we serve 100 million users?" You talk about servers, load balancers, database replicas and sharding (splitting data across many machines).

A mobile round asks: "How does one app on one phone give a great experience?" The server is mostly a black box. You care about the device and the user.

TopicBackend roundMobile round
Main limitServer CPU, storage, trafficMemory, battery and network on one device
NetworkFast and stable, inside a data centerSlow, flaky, sometimes offline
ScaleMillions of requests per secondOne user, many screens, many app versions
Source of truthThe databaseA local copy and a server copy that must stay in sync
ReleasesDeploy many times a dayApp Store review, users update slowly
FailureRetry on another serverShow a clear message, keep working offline
Extra topicsSharding, replication, load balancingLifecycle, main thread, permissions, accessibility

The release row matters a lot. You cannot hotfix a shipped app. Old versions stay on phones for months. So your design needs feature flags, a stable API, and a way to force an update.

How much server design you need

You still talk about the server, but only where it touches the app:

  • the endpoints the app calls
  • the data format (usually JSON)
  • how the server sends updates (push notifications, WebSocket)
  • pagination (loading a long list one page at a time)

You do not design the database cluster. If the interviewer wants more backend, they will ask.

The right level is the contract between app and server. Write it as Swift:

import Foundation

// The app's view of the server. This is enough detail for a mobile round.
protocol FeedAPI: Sendable {
    func fetchFeed(cursor: String?, limit: Int) async throws -> FeedPageDTO
    func like(postID: String) async throws
}

struct FeedPageDTO: Decodable, Sendable {
    let posts: [PostDTO]
    let nextCursor: String?
}

struct PostDTO: Decodable, Sendable {
    let id: String
    let authorName: String
    let imageURL: URL
    let likeCount: Int
}

What interviewers check

Most companies score the same six things:

  1. Structure. You have a plan. You go from the big picture to the details.
  2. Requirements. You ask questions before you design.
  3. Architecture. The parts are clear. Each part is easy to test and to change.
  4. iOS depth. You know caching, offline, threading, memory and the app lifecycle.
  5. Trade-offs. You say why you chose A over B, and what you lose.
  6. Communication. You think out loud. You check in with the interviewer.

You do not need to know everything. You need good judgment. This sentence shape works very well:

"I would start simple with X. If we see problem Y, I would move to Z."

Expectations by level

LevelA good answer shows
MidClear layers, a clean data model, a working API, basic caching, loading and error states
SeniorAll of the above, plus offline, sync, real-time updates, performance, testing and clear trade-offs
StaffAll of the above, plus modules for many teams, rollout, metrics, and how the design grows over time

A senior candidate leads the conversation. A mid-level candidate can take more hints. Both are fine for their level.

What you can skip

Do not spend time on:

  • pixel-level UI, colors and fonts
  • the full server database schema
  • complete, working code

A few Swift types and protocols are enough. They make your design concrete. For example, this one type shows that you thought about every screen state:

enum LoadState<Value> {
    case idle
    case loading
    case loaded(Value)
    case empty
    case failed(message: String)
}

It takes ten seconds to write. It saves you five minutes of talking.

A tiny example of the whole flow

Here is the shape of a good answer to "Design a photo feed", in six lines:

1. Requirements: scroll a feed, like a post, works offline (read only), smooth scrolling.
2. Architecture: FeedView -> FeedViewModel -> FeedRepository -> (FeedAPI, FeedStore).
3. Data model:   Post, User, FeedPage (with a cursor).
4. API:          GET /v1/feed?cursor=..., POST /v1/posts/{id}/like.
5. Deep dives:   image loading and caching, pagination, offline cache.
6. Wrap-up:      trade-offs, metrics, rollout behind a feature flag.

The next chapters fill in each line.

How to use this guide

The chapters follow the order of a real interview:

  1. Framework: how to split the 45 minutes.
  2. Requirements: what to ask and what to write down.
  3. Architecture: layers, modules and dependency injection.
  4. Data and APIs: models, storage, REST or WebSocket, pagination.
  5. Deep dives: caching, offline, real-time, images, background work, concurrency, errors.
  6. Performance and observability: launch time, scrolling, memory, logs, metrics, rollout.
  7. Common mistakes: weak answers and better versions.

Read them once in order. Then practice with real prompts. Set a 45-minute timer and answer out loud. Practice is what makes the real round feel calm.