Design a Simplified WhatsApp: Message Send and Receive, Schema, and Scaling
FivetranSoftware Engineer · Technical ScreenLast updated
Design a simplified WhatsApp focused on sending and receiving messages: the online and offline delivery flow, client APIs, the database schema, and scaling. It tests connection routing, delivery guarantees and ordering, and a choice between relational and NoSQL storage justified by access patterns.
Design a simplified version of WhatsApp. Focus on the core messaging path: one user sends a message, and the recipient receives it. Cover the send and receive flow, the database schema, and how the system scales. Expect to defend your storage choice, including when a relational database or a NoSQL store is the better fit.
Clarifying Questions
- Is the scope one-to-one chats only, or group chats as well?
- Must messages reach recipients who are offline when the message is sent, and how long does the server keep undelivered messages?
- Does the server keep the full chat history, or only messages that have not been delivered yet?
- Are delivery and read receipts in scope? Media attachments? Several devices per user?
- What scale should the design target (daily active users, messages per day, peak rate)?
- What ordering guarantee do users expect within a conversation?
Part 1 — Sending and receiving messages
Describe the end-to-end flow when a user sends a message and the recipient receives it, both when the recipient is online and when they are offline. Define the client-facing APIs.
What This Part Should Cover
- Low-latency delivery to online recipients, and the connection model that makes it possible
- Delivery to offline recipients, and resynchronization when they reconnect
- Acknowledgements and retries, and how duplicates and ordering are handled
- Client-facing APIs
Part 2 — Database schema and the storage choice
Design the database schema for users, conversations, and messages, and choose the storage technology. Explain when a relational database would be the better fit and when a NoSQL store would be.
What This Part Should Cover
- Tables or collections with their keys, and how message order is represented
- The dominant access patterns, and how the keys serve them
- A reasoned comparison of relational and NoSQL storage for each kind of data, beyond general statements
Part 3 — Scaling
Explain how the system scales as the number of users and the message volume grow.
What This Part Should Cover
- Horizontal scaling of the connection layer, and routing a message to the server that holds the recipient's connection
- Partitioning of message storage, and handling of hot partitions
- Failure handling for servers, connections, and storage
Hints
Hint 1
Think about the connection: Consider how the server reaches a recipient who is online right now, and what has to be true for a message sent while they were offline to reach them later.
Hint 2
Start from the access patterns: List the reads and writes the messaging path performs most often, then choose keys and a store that serve them efficiently.
Hint 3
Find what grows: Identify which components hold per-connection state and which hold per-message data, and scale each along its own axis.
Follow-up questions
- How would you add group chats with many members, and what changes in the send path and the schema?
- How would you support one user signed in on several devices, each of which needs every message exactly once?
- If messages are end-to-end encrypted, what can the server still store and index, and what changes in your design?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.