WhatsApp is a free messaging app that lets people send texts, voice messages, photos, videos, and make voice or video calls over the internet. It uses your phone number as your identity and offers end-to-end encryption, meaning only you and the recipient can read or hear your messages.
Product Design Requirements
Functional Requirements
- Users should be able to create chat groups with multiple participants (up to 100 members).
- Users should be able to send and receive messages.
- Users should be able to receive messages even when they are offline.
- Users should be able to send and receive media content (e.g., images and videos) within chats.
Non-Functional Requirements
- The system should prioritize availability over strict consistency.
- The system should deliver messages with low latency (less than 500ms)
- The system should support high throughput, scaling to billions of users (target: 2B users).
- The system should be fault-tolerant and resilient to component failures.
- Messages should not be retained longer than necessary, adhering to efficient storage and privacy considerations.
Design Setup
Data Model
- User represents a logical account (
userId,name,profile info). A single user may be logged in on multiple devices. - Message represents a message within a chat. It includes
messageId,chatId,senderUserId,clientMessageId(for deduplication), content/attachments, and createdAt. - Chat represents a conversation (1:1 or group). It stores metadata like
chatId,chatType,name, andtimestamps. Membership is handled via a ChatParticipant mapping between users and chats. - Client represents a specific device/session (e.g., phone, web). It includes
clientId,userId,device type, andconnection status. This is important because message delivery and acknowledgments often happen at the device level.
API Design
For a chat system like WhatsApp, a traditional REST API is not ideal due to the need for high-frequency, real-time message exchange. Instead, we use a bi-directional WebSocket connection (over TLS), allowing clients to maintain a persistent connection with the server for low-latency communication. We can define the system interface as a set of commands over this connection:
- createChat → create a new chat with participants
{ "participants": ["user1", "user2"], "name": "group name" } -> { "chatId": "" }
- sendMessage → send a message (with optional attachments)
{ "chatId": "", "message": "", "attachments": [] } -> { "status": "SUCCESS" | "FAIL", "messageId": "" }
- createAttachment → upload media and get an attachmentId
{ "body": "...", "hash": "" } -> { "attachmentId": "" }
- modifyChatParticipants → add/remove users from a chat
{ "chatId": "", "userId": "", "operation": "ADD" | "REMOVE" } -> "SUCCESS" | "FAIL"