Mobile system design interviews ask you to design a real product feature — a social feed, a chat system, an offline-capable notes app, a video streaming player — in 45–60 minutes. The interviewer is not looking for the perfect answer. They are watching how you think: do you clarify scope, identify trade-offs, drive the conversation, and arrive at reasonable decisions under ambiguity?
The Framework
Use a consistent structure for every question. Experienced interviewers recognize when a candidate is structured and when they are winging it.
1. Clarify requirements (5 min) Ask before designing. This is not stalling — it is how real engineers work.
- What is the primary platform? Android only, or cross-platform?
- What is the scale? How many users, DAU, content items?
- Are there constraints — offline support, battery, bandwidth, specific device tiers?
- What features are in scope? What is explicitly out of scope?
2. Define the core entities and data model (5 min)
User { id, name, avatarUrl }
Post { id, authorId, content, mediaUrl, createdAt, likeCount }
Feed { userId, posts: List<Post>, nextCursor }
Naming entities early gives the interview a shared vocabulary and forces clarity about what the system actually stores.
3. Draw the architecture (15 min)
Sketch the layers from UI to server:
Composables / Screen
↓ state, events
ViewModel + UI state
↓ use cases
Repository
↓ ↓
Remote source Local source
(Retrofit/API) (Room/DataStore)
Identify the key architectural decisions: single source of truth, how caching works, where pagination lives, how sync is triggered.
4. Walk through each layer (15 min)
Go deep on the areas the interviewer cares about. Typical areas for mobile:
- State management: What is the shape of
UiState? What triggers recomposition? - Pagination:
PagingSourcevs manual cursor-based paging. How does the UI handle loading more? - Offline-first: What data is cached? What happens on a failed write?
- Networking: How are failures handled? Retry logic? Exponential backoff?
- Performance: How is the feed list efficient? Image loading strategy?
5. Identify trade-offs and alternatives (5 min)
Every design has trade-offs. Name them.
- "I chose to cache only the last 50 posts to bound storage. The trade-off is that users who scroll deep will always hit the network."
- "I am using a
RemoteMediatorto sync from the server into Room. An alternative is a pure in-memory cache, which is simpler but loses data on process death."
6. Handle follow-up questions
The interviewer will probe the areas you skimmed. Be honest when you reach the edge of your knowledge. "I know the general approach but I haven't implemented it — I would investigate X" is a better answer than guessing.
Worked Example: Design an Instagram-like Feed
Clarify: Home feed of posts from followed accounts. Infinite scroll. Images only (no video for now). Must work with intermittent connectivity. No DMs, stories, or Reels in scope.
Entities:
data class Post(
val id: String,
val authorId: String,
val authorName: String,
val avatarUrl: String,
val imageUrl: String,
val caption: String,
val likeCount: Int,
val isLikedByMe: Boolean,
val createdAt: Instant
)
data class FeedPage(
val posts: List<Post>,
val nextCursor: String?
)
Architecture decision: offline-first with Room + RemoteMediator
Room is the single source of truth. The UI always reads from Room. When the user opens the app or scrolls to the end, RemoteMediator fetches from the API and writes to Room. The UI automatically sees the update through Flow.
@OptIn(ExperimentalPagingApi::class)
class FeedRemoteMediator(
private val api: FeedApi,
private val db: AppDatabase
) : RemoteMediator<Int, PostEntity>() {
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, PostEntity>
): MediatorResult {
return try {
val cursor = when (loadType) {
LoadType.REFRESH -> null
LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
LoadType.APPEND -> db.remoteKeyDao().getNextCursor()
}
val response = api.getFeed(cursor = cursor, limit = state.config.pageSize)
db.withTransaction {
if (loadType == LoadType.REFRESH) {
db.postDao().clearAll()
}
db.postDao().upsertAll(response.posts.map { it.toEntity() })
db.remoteKeyDao().save(RemoteKey(nextCursor = response.nextCursor))
}
MediatorResult.Success(endOfPaginationReached = response.nextCursor == null)
} catch (e: IOException) {
MediatorResult.Error(e)
}
}
}
State model:
data class FeedUiState(
val feed: LazyPagingItems<Post>, // driven by Pager
val isOffline: Boolean = false
)
Trade-offs to name:
- Caching all posts in Room means the database grows. Address with a TTL-based eviction strategy.
RemoteMediatoradds complexity. For a simpler app, an in-memory list with manual pagination is easier to reason about.- Images are not cached in Room — we rely on Coil's disk cache. If the user is offline and Coil's cache is cleared, images disappear.
Worked Example: Design a Chat Screen
Key decisions:
- Real-time: Use WebSocket (OkHttp) for incoming messages. Keep the connection alive in a
Serviceor a background coroutine scope tied to the app lifecycle. - Persistence: Store messages in Room. The UI observes
Flow<List<Message>>from the DAO. - Optimistic updates: When the user sends a message, insert it into Room immediately with status
PENDING. The network call updates the status toSENTorFAILED. - Pagination: Load recent messages and page upward on scroll.
LazyColumnwith reversed item order is a common pattern.
What Interviewers Penalize
| Pattern | Problem |
|---|---|
| Jumping to code before discussing architecture | Misses the design intent |
| "It depends" with no follow-up | Not a real answer — always say what it depends on |
| Over-engineering for requirements that were not stated | Wasted discussion time |
| Ignoring offline, errors, or edge cases | Shows junior thinking |
| Not driving the conversation | Looks passive; good engineers lead the design |
Practice Structure
For the next 4 weeks, pick one real app per week and design it from scratch:
- Week 1: News feed reader (pagination, caching, offline)
- Week 2: Ride-hailing passenger app (real-time location, map, state machine)
- Week 3: E-commerce product page with cart (optimistic updates, inventory)
- Week 4: Podcast player (background audio, download manager, progress sync)
For each: write the UiState, sketch the architecture, pick the key trade-offs, and write the most important DAO or API interface.
Summary
Mobile system design interviews reward structured thinking, clear trade-off reasoning, and practical knowledge of Android-specific concerns — pagination, offline support, state management, and real-time data. Use the six-step framework consistently. Drive the conversation. Name trade-offs before the interviewer asks about them. Practice with real app scenarios, not abstract systems.