Design a messaging service around three separate facts: the server accepted a message, a device received it, and a person read it.
Interview scope and guarantees
Send one-to-one messages, synchronize devices, retrieve offline history, and distinguish accepted, delivered, and read receipts. Agree group size and retention before adding groups. The transport may reconnect; durable message identity must survive it.
Capacity worksheet
Assume 10 million users send 50 messages/day: 500 million/day, about 5,787 writes/s average and 28,935/s peak at 5×. At 1 KB/message that is 500 GB/day raw before replicas and indexes. Ten million simultaneous connections at 10 KB of server state each require about 100 GB spread across gateway instances.
Concrete API contract
POST /conversations/{id}/messages {clientMessageId,ciphertext}
GET /conversations/{id}/messages?afterSequence=...
POST /receipts {messageId,deviceId,status}
WebSocket resume {conversationId,lastSequence}Data model and access paths
messages(conversation_id,sequence,message_id,ciphertext); PK(conversation_id,sequence)
client_keys(conversation_id,sender_id,client_message_id,request_hash,message_id); UNIQUE(conversation_id,sender_id,client_message_id)
device_cursors(user_id,device_id,conversation_id,last_delivered)
memberships(conversation_id,user_id,version)Evolve a solution and explain each change
Figure — Three architecture decisions for WhatsApp, including the pressure each introduces.
Step 1: Persist before acknowledging
Store a conversation message and sender retry identity. A socket acknowledgement alone does not mean durable acceptance.
Step 2: Deliver across devices
Use per-device cursors and replay from the message log after reconnect. Online push can be lost; receipt states can be conflated.
Step 3: Separate state and content
Track accepted, delivered, and read receipts with bounded fanout and encrypted payloads. Encrypted content does not remove metadata or membership risks.
Responsibility overview
Figure — Connected responsibilities for WhatsApp. Trace the authoritative and derived paths separately.
Worked end-to-end scenario
A sender transmits message m7, but the response disappears. Its retry uses the same client message ID, so the server returns the existing accepted sequence. Recipient phone P is offline; laptop L is online and receives a wake-up. Each device pulls after its own cursor. P reconnects later and retrieves m7 from durable history. A delivered receipt means a specified device acknowledged receipt; a read receipt requires a distinct user action and privacy policy. Neither should be synthesized from successful database insertion. Group membership changes must determine which message versions a device may fetch.
Why these access paths matter
Partition messages by conversation and order by server sequence with a stable identity. Deduplicate by sender and client message ID within the conversation. Store per-device checkpoints separately from message content. For very large groups, explain whether writes fan out recipient references or reads fetch a shared log; both approaches still enforce membership.
Build the baseline first
- Sender → message API → durable append and sequence.
- Delivery worker → recipient gateway → device.
- Offline device → history cursor → missing messages.
Evolve the design under load
- Conversation partitions → independent append owners.
- Connection directory → regional gateway fleet.
- Media attachment → object storage → encrypted reference.
Defend the hardest decision
Per-conversation sequence numbers express server order; device timestamps do not reliably do so. The server acknowledges acceptance after durable commit. Delivery means a specific device acknowledged the message; read receipts are a separate user action. On reconnect, replay after the durable device cursor and deduplicate by message ID. Exactly-once presentation is a client/storage property built over potentially repeated delivery.
Failure and recovery analysis
The gateway sends a message but crashes before receiving acknowledgement. Resend on reconnect; the device upserts by message ID. For a membership removal, ensure the authorization epoch used to distribute future messages is current. End-to-end encryption changes what servers can search or moderate; do not promise plaintext server search while also claiming the server cannot decrypt.
Security and privacy boundary
Authenticate devices and membership, rotate or revoke device sessions, and protect metadata as well as message bodies.
Interview follow-ups with reasoning
Question: What if two devices send concurrently?
Show answer and explanation
Answer: Order at the conversation authority and keep distinct client message IDs.
Question: How do large groups change cost?
Show answer and explanation
Answer: Bound fanout and consider per-group log reads with device cursors.
Question: How do you handle presence?
Show answer and explanation
Answer: Treat it as ephemeral and approximate, never as proof of delivery.
Operate and verify the design
Acceptance latency, per-device delivery lag, reconnect replay gaps and duplicate presentation.
Disconnect after message commit but before acknowledgement, then replay the same client message ID.
A second scenario to test transfer
Alice sends while Bob’s phone is connected and his laptop is offline. The server accepts once, routes to the phone, and retains mailbox history. Bob’s phone acknowledges sequence 81. The laptop later resumes after 74 and fetches 75 through 81. Alice’s interface can show delivery according to the product’s receipt rule without pretending every device has caught up.
Bob’s phone acknowledges a message. May the service delete it before Bob’s laptop reconnects?
Show answer and explanation
Answer: Only if the retention and synchronization contract allows that loss. Device progress is distinct. Keep recoverable history or an appropriate encrypted backup/snapshot mechanism for the supported offline horizon.
Compare alternatives
| State | What it proves | What it does not prove |
|---|---|---|
| Accepted | Server durable boundary met | Recipient is online |
| Delivered | Specified device acknowledged | Every device synchronized |
| Read | Read action under product rules | Permanent human comprehension |
A design-changing exercise
The sender sees a successful API response. Can the UI show read?
Show answer and explanation
Answer: No. Acceptance, delivery, and reading are separate events with different evidence and privacy semantics.
Design workshop: conversation order and device progress
Choose one-to-one messages, bounded groups, multiple devices and offline catch-up as core. Calls are excluded. Assume server acceptance under 200 ms in the conversation home region, online delivery within one second under healthy conditions and a 30-day offline history contract. Those latency targets do not override durable acceptance or authorization.
Retry identity is unique(conversation_id,sender_id,client_message_id). The same identity with changed encrypted content returns 409. A conversation owner allocates a server sequence and inserts the message, request mapping and delivery intent in one durable transaction. It acknowledges accepted only after that boundary. On failover, a higher owner epoch prevents the old process assigning more sequences; an in-memory counter restored below the log head is unsafe.
Figure — Two devices consume one durable message.
Store device_cursors(conversation,recipient,device_id,delivered_seq,read_seq), keyed by all three identities. Monotonic max updates make duplicated receipts safe. In this scenario sender-visible delivered means at least one recipient device acknowledged; read means an eligible recipient device reported read. Another product can choose all devices, but cannot infer that from one device's receipt. A group needs per-recipient receipts or bounded aggregate counts with a clear meaning.
Figure — Message and receipt state boundaries.
For bounded groups, persist once and create recipient mailbox references asynchronously under unique(message,recipient). Offline mailbox history survives a failed socket push. A gateway session registry locates online devices; it is not the message authority. At 1,000 recipients, a group message can create 1,000 delivery references and far more device sends. Shard delivery by recipient and cap group size/admission rather than assume one append implies one delivery operation.
If end-to-end encryption is in scope, choose an established protocol implementation rather than inventing cryptography. Device registration publishes authenticated identity/prekey material; senders encrypt to authorized recipient devices, and device additions require identity verification and membership updates. A group membership change rotates the group encryption epoch under the chosen protocol. The server stores ciphertext and delivery metadata; it cannot offer ordinary plaintext server-side search under that same guarantee. Backup/recovery keys and trust on new device registration need a separate threat model.
Removal from a group changes admission and history authorization at a membership version. This scenario denies new events to removed members and does not claim to erase bytes already downloaded. Push workers recheck membership before sending protected payload. If historical access after removal is allowed, encode that distinct policy instead of using current membership alone.
Exercise: Phone acknowledges 81, laptop is at 74, and sequence 75 reaches the end of retention. May phone's receipt delete all message history?
Show answer and explanation
Answer: Not under the 30-day per-device catch-up contract. Device cursors differ. Retain supported history or provide an explicit reset/backup path after expiry; accepted, delivered and retained-for-all-devices are different guarantees.
Signal specifications are a reference for established encryption protocols, not permission to describe a toy key exchange as production-safe E2EE.
Technical references
Bob’s phone acknowledges a message. May the service delete it before Bob’s laptop reconnects?
Your design draft
Clarify assumptions, explain your approach, and test the difficult cases. Save your draft, then compare it with the study notes.
Self-review checklist
Self-guided practice. Automated AI feedback and code execution are not connected.