Free lesson · Mobile System Design Interviews
Chat Application - Problem & Discovery
Think Before You Speak
When a system design interviewer says "Design a mobile chat application," your brain needs to shift into a different gear than when you heard "Design a social feed."
Why? Let's think about this with a simple analogy. In a social feed, you're reading messages that were already written - you're consuming content at your own pace. If a photo arrives 10 seconds late, nobody cares. The feed is pull-based: you refresh to see what's new.
A chat application is the opposite. Messages flow back and forth in real time, like a conversation. If Alice sends "Hello," Bob should see it almost instantly - not 10 seconds from now. The experience breaks down entirely if messages arrive out of order or if people can't send when they're offline.
This single insight - real-time bidirectional communication - shapes every architectural decision we make.
What Makes Chat Apps Different
Let's spell out exactly what makes chat systems unique:
-
Bidirectional data flow: Both client and server need to push data to each other. The phone doesn't just pull messages; the server pushes them.
-
Message ordering guarantees: We can't have Bob reading messages in the wrong sequence. Timestamps aren't reliable (clocks drift), so we need server-assigned sequence numbers.
-
Delivery and read receipts: "Is this message on Alice's device?" "Has she read it?" These questions matter in chat. They barely matter in a social feed.
-
Offline queuing: Your phone should buffer unsent messages locally. When connectivity returns, they should send automatically.
-
Persistent local storage: Every message must be stored on the device. Unlike a social feed where you scroll down and forget the old posts, you want to scroll back through weeks of conversation.
-
Low-latency expectations: Users expect sub-second delivery. A 5-second delay feels broken. This isn't just nice-to-have; it's table stakes.
The Problem Statement
Design the mobile client for a real-time messaging application.
The app allows two users to exchange text messages in real time. Your job is to architect the iOS and Android clients to handle this reliably, even with poor connectivity, and to deliver a smooth, responsive user experience.
Step 1: Requirements Clarification
Here's how this conversation with an interviewer might go:
Candidate: "Before I jump into architecture, let me clarify what we're building. Is this one-on-one messaging only, or do we need to support group chats?"
Interviewer: "Good question. Let's start with one-on-one. Group chats can be a follow-up."
Candidate: "Got it. Text only for now, or do we need to support images and media?"
Interviewer: "Let's assume text for the core design. Media can be added later."
Candidate: "Makes sense. Let me ask about the experience when the phone is closed or the app is backgrounded. Do we need to support push notifications?"
Interviewer: "Yes, absolutely. Users should be notified of new messages even when the app isn't running."
Candidate: "Should the notification show a preview of the message, or just 'You have a new message'?"
Interviewer: "Show a preview if possible. Users expect that."
Candidate: "Understood. What about features like 'Alice is typing' or online status? Are those required?"
Interviewer: "Nice to have. If time, implement typing indicators. Online status is less critical but reasonable."
Candidate: "Are these conversations end-to-end encrypted, or is server-side encryption fine?"
Interviewer: "For now, assume the server can see messages. E2E encryption is a separate deep dive."
Candidate: "Does message history persist forever, or do we delete old messages?"
Interviewer: "Persist forever on the server. Let the user manage device storage."
Candidate: "When a user sends a message, how do they know it actually arrived? Do we need read receipts?"
Interviewer: "Yes. Show three states: sent (checkmark), delivered (double checkmark), read (blue double checkmark)."
Candidate: "How many concurrent users should the system handle?"
Interviewer: "Assume millions of daily active users. No single point of failure."
Candidate: "And offline? If someone's phone has no connectivity, what happens?"
Interviewer: "Buffer the message locally. Send it as soon as connectivity returns."
Functional Requirements
Based on this conversation, here's what we need to build:
- Send messages: A user can type and send a text message to another user.
- Receive messages in real time: A recipient's app updates instantly when a message arrives.
- Message history: Scroll back through old conversations.
- Message status tracking: Show if a message is pending, sent, delivered, or read.
- Delivery receipts: Automatically send a receipt when a message is received.
- Read receipts: Automatically send a receipt when a message is read.
- Typing indicators: Show when the other person is typing.
- Online status: Display whether the other user is currently online.
- Offline support: Queue unsent messages locally; send when network returns.
- Push notifications: Alert the user to new messages even when the app is backgrounded.
- Conversation list: Show a list of active conversations, sorted by most recent.
Non-Functional Requirements
These are the properties the system must exhibit:
- Real-time delivery: Messages should arrive in under 1 second under normal network conditions.
- Reliability: No message loss. If a send request fails, the app must retry intelligently.
- Message ordering: Messages must be displayed in the exact order they were sent, globally.
- Data integrity: No duplicates (sending the same message twice should create one message, not two).
- Scalability: Handle millions of concurrent users without degradation.
- Offline resilience: The app must work smoothly when connectivity is unavailable; state syncs when the network returns.
- Battery efficiency: Minimize background activity and network usage.
- Low memory footprint: Store message history without consuming excessive RAM or storage.
Out of Scope
Let's be explicit about what we're not designing in this case study:
- Group chats (multiple recipients)
- Media attachments (images, videos, voice messages)
- End-to-end encryption
- Message search
- Call integration (voice/video)
- Message reactions or editing
- User authentication (assume the user is already logged in)
- Account creation or profile management
- Server-side infrastructure (we'll reference APIs but not design the backend)
UI Sketch Description
If you were sitting with a pen and paper, here's what you'd sketch:
Screen 1: Conversation List
- A list of conversations, each showing the other person's name, their avatar, and a preview of the last message.
- Conversations sorted with most recent at the top.
- Each item shows the timestamp of the last message.
- A "+" or "New Chat" button to start a conversation.
Screen 2: Chat / Conversation View
- A vertical scroll of messages, with the oldest at the top.
- Messages from the current user appear on the right side, in one color (say, blue).
- Messages from the other user appear on the left, in another color (say, gray).
- Each message shows: the text, a timestamp, and status indicators (checkmark for sent, double-check for delivered, blue checkmark for read).
- At the bottom: a text input field and a send button.
- Above the input field, a subtle indicator if the other person is typing: "Alice is typing..."
- Also near the name at the top: an indicator of whether Alice is online.
Screen 3: Push Notification (when app is closed)
- A notification that says something like "Alice: Hey, what are you up to?" with the option to tap and open the conversation directly.
What's Next
Now that we've defined the problem, our next step is to design the API layer: what endpoints does the mobile client call, and how does real-time data flow happen?
In the next section, we'll make the biggest architectural decision: HTTP for sending, WebSocket for receiving. This hybrid approach is the backbone of modern chat systems.