01Just 1:1 chat, or groups too — and how big can a group get?
Users send and receive messages in 1:1 and group chats — groups capped around 100 participants, which keeps fan-out per message bounded.
Free full guide
Design Facebook Messenger — a real-time chat system delivering messages with low latency, ordering guarantees, and multi-device sync at massive scale.
The interview rhythm stays compact, so the page can spend attention on the actual design decisions.
Do not only state requirements. Ask for them. Each card pairs the design constraint with a clarification question you can say out loud before drawing the architecture.
01Just 1:1 chat, or groups too — and how big can a group get?
Users send and receive messages in 1:1 and group chats — groups capped around 100 participants, which keeps fan-out per message bounded.
02What happens to messages sent while I am offline?
Offline messages are delivered on reconnect from a per-user inbox, kept up to 30 days — the server is a relay with a buffer, not a permanent archive.
03One phone per user, or every device in sync?
Users can attach media, and every device a user owns stays in sync — each device tracks its own delivery state.
04Read receipts and typing indicators - in scope?
Receipts yes: they ride the same per-device delivery machinery as messages. Typing indicators are ephemeral presence - best effort, never stored.
05Can users delete a sent message for everyone?
Delete-for-everyone is a tombstone event that propagates exactly like a message; clients that already rendered it replace it in place. Edits stay out of scope.
06Someone joins or leaves a group mid-conversation - what do they see?
Membership changes are ordered events in the chat: joiners receive from the join point onward, leavers stop receiving at the leave event - never partial history.
Out of scopeAudio and video calling · Business messaging and chatbots · Registration and profile management
01How fast must a message reach someone who is online?
Under 500 ms end to end — chat feels instant or it feels broken.
02Can a message ever silently vanish?
No — deliverability is guaranteed: the message is durably written before any delivery attempt, so a dropped connection delays it, never loses it.
03What scale are we designing for?
Hundreds of millions actively messaging; roughly 46K messages per second sent, ~100K writes per second once group fan-out is counted.
04How long do servers keep message content?
No longer than necessary: a 30-day TTL (time-to-live) on the undelivered inbox, then gone.
05What happens when a chat server dies?
Its users reconnect elsewhere and sync from the inbox — because delivery state lives in storage, not in the server’s memory, no message is lost.
Real interviews probe far more than a tidy list. These are the scope questions that separate candidates who interrogate the problem from those who recite it.
Treat every estimate as a pressure that justifies a component: cache, queue, partition, replica, worker pool, or fallback path.
Message write rate
200M active users × ~20 messages/day4B ÷ 86,400 s ≈ 46K msg/s sent · group fan-out ×2-3 ≈ 100K writes/s
Write-optimized storage (LSM log-structured merge trees / wide-column) for Message + Inbox; fan-out work scales with participants, which is why groups are capped.
Connections per gateway
~1M concurrent WebSocket connections per beefy gateway box100M concurrently online ÷ 1M ≈ 100+ gateways
Users hash to gateways (consistent hashing + registry) so message routing can find the right box.
Cross-server delivery
Sender on gateway A, recipient on gateway Bpublish to recipient’s user channel → only B (subscribed) forwards
Pub/sub partitioned BY USER ID keeps each gateway subscribed only to its own users — partitioning by chat would make busy groups hot.
Why durable-write-first
Pub/sub is at-most-once: a dropped subscriber loses the publishwrite Inbox + Message BEFORE publish → worst case = late, never lost
The inbox turns every delivery failure into a reconnect sync instead of a support ticket.
Offline inbox size
30-day TTL, ~1KB per message referenceeven 1,000 undelivered msgs ≈ 1 MB per dormant user
TTL keeps the backstop bounded; long-dormant devices resync history from the Message store instead.
Decision example
A hundred thousand writes a second, a hundred million people online at once, and a promise: under half a second, and nothing ever silently lost.
I would keep gateways stateless: a gateway only holds sockets and forwards — every message is durably written to the Message store and each recipient’s Inbox BEFORE any push. Cross-server delivery rides pub/sub partitioned by user ID, so each gateway subscribes only to its own connected users. Heartbeats every 10-30 seconds carry the latest sequence number, so a client that missed anything detects the gap and pulls it. Order is server receipt time — fast beats perfectly ordered in chat.
What I would NOT do: keep undelivered messages in gateway memory — one crash and they are gone, which breaks the core promise. I would not partition pub/sub by chat ID — one busy group turns into a hot partition; partition by user instead. And I would not add sharding layers before measuring the actual per-partition message rate — premature sharding adds failure modes, not capacity.
If end-to-end encryption becomes in scope, the server degrades to a blind router of ciphertext: inbox and multi-device sync must move to per-device message copies and client-held keys.
Draw the write path and the read path as separate lanes — they carry different traffic and justify different components.
Durable write first, delivery second. Gateways are stateless socket-holders; the registry knows who is connected where, and offline devices get a push instead of a socket frame.
The sender’s ack fires after the durable write; pub/sub then reaches every gateway holding a recipient device. A missed publish is safe — the inbox already has it.
On reconnect the client drains its inbox and compares sequence numbers; anything missed in transit is pulled, then real-time delivery resumes.
Before optimizing, make the contract inspectable: endpoints, entities, ownership, retries, and state.
WSsendMessage { chat_id, body, attachments[] }
res{ message_id, status } — ack after durable write
The ack means "stored", not "delivered" — durability first, delivery second.
WSnewMessage → client { chat_id, sender, body }
resclient replies RECEIVED
Pushed over the persistent connection to every online device of every participant.
POST/attachments
req{ body: presigned upload }
res200 { attachment_id, url }
Media goes to blob storage via presigned URL; messages carry only the opaque reference.
WSheartbeat every 10-30 s (piggybacks last sequence)
resclient compares and syncs gaps
Heartbeats detect dead connections AND double as the gap-detection channel.
Core entities
Chatchat_id (PK) · participants (≤100) · name
Messagemessage_id (PK) · chat_id · sender_id · body · attachments · server_ts
Ordered and displayed by server receipt timestamp — users would rather see messages fast than in perfect send order.
Inboxuser_id (PK) · message_id · ttl_30d
The durability backstop: written BEFORE any push attempt, drained on reconnect.
Clientuser_id (PK) · client_id · last_seen
One user, several devices (~3 cap) — delivery is tracked per client, not per user.
Pick one lane for the final third of the interview. Each lane gives you the topic, the interviewer question it should answer, and the failure mode to avoid.
FocusA hundred million open sockets
AskHow do hundreds of millions of users hold persistent connections, and how does a message find the one gateway holding its recipient?
AvoidBroadcasting every message to every gateway — subscribe gateways only to their own connected users.
FocusThe recipient is offline
AskWhere does the message wait, for how long, and what happens the moment they reconnect?
AvoidRelying on pub/sub for durability — it is at-most-once; the inbox write must come first.
FocusTwo phones, one account
AskA user reads a message on their laptop. What does their phone need to know, and how is per-device state tracked?
AvoidTracking delivery per user instead of per client — the second device silently misses messages.
FocusMessages arrive out of order
AskTwo messages race through different gateways. What order does the recipient see, and why is that acceptable?
AvoidBlocking delivery to enforce global order — users prefer fast over perfectly sequenced.
FocusA gateway dies mid-conversation
AskTen thousand users drop at once. What do they lose, and how fast are they whole again?
AvoidAny design where gateway memory is the only copy of an undelivered message.
Talk through Facebook Messenger out loud and get AI scoring on the explanation.