Free full guide

Facebook Messenger

Design Facebook Messenger — a real-time chat system delivering messages with low latency, ordering guarantees, and multi-device sync at massive scale.

00

Practice checkpoints

The interview rhythm stays compact, so the page can spend attention on the actual design decisions.

  1. 01
    Clarify scope
  2. 02
    Requirements + scale
  3. 03
    API + data model
  4. 04
    Draw architecture
  5. 05
    Deep dive
  6. 06
    Trade-off decision
01

Requirements that shape the design

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.

Functional requirements

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 are capped around 100 participants, which keeps the fan-out per message bounded.

02What happens to messages sent while I am offline?

Messages sent while offline are delivered when the device reconnects. They are kept for up to 30 days. The server is a relay with a limited 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 path as messages. Typing indicators are temporary. They are best effort, and never stored.

05Can users delete a sent message for everyone?

Delete-for-everyone is a tombstone event that travels exactly like a normal message. Clients that already showed the message replace it in place. Edits stay out of scope.

06Someone joins or leaves a group mid-conversation - what do they see?

Joining or leaving a group is an ordered event in the chat. People who join receive messages from the join point onward. People who leave stop receiving at the leave event. Nobody gets partial history.

Out of scopeAudio and video calling · Business messaging and chatbots · Registration and profile management

Non-functional requirements

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 but never loses it.

03What scale are we designing for?

200M daily actives sending ~20 messages a day, with roughly half of them online at any moment.

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 to another server and sync from the inbox. Delivery state lives in storage, not in the server’s memory, so no message is lost.

Keep asking — the interview is a conversation

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.

  • Group size cap — hundreds or thousands? Fan-out design hangs on it.
  • Is "delivered to server" or "delivered to device" the ack the sender sees?
  • How many devices per account should stay in sync?
  • Is message history a permanent archive, or a 30-day relay buffer?
  • Is end-to-end encryption in scope? It changes what the server can store.
02

Numbers that force architecture decisions

Treat every estimate as a pressure that justifies a component: cache, queue, partition, replica, worker pool, or fallback path.

01

Message write rate

200M active users × ~20 messages/day200M × 20 = 4B messages/day; 4B ÷ 86,400 s ≈ 46K msg/s sent; group fan-out ×2-3 ≈ 100K writes/s

Message and Inbox need write-optimized storage (LSM log-structured merge trees / wide-column). Fan-out work grows with the number of participants, which is why groups are capped.

02

Concurrent connections

200M daily actives, roughly half online at any moment200M × ~50% ≈ 100M open WebSocket connections

With persistent sockets, connection count is what sizes the gateway fleet, not request rate.

03

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.

04

Offline inbox size

30-day TTL, ~1KB per message referenceeven 1,000 undelivered msgs ≈ 1 MB per dormant user

The TTL keeps the backstop small. Long-dormant devices resync their history from the Message store instead.

Decision example

The numbers

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.

My choice

Keep the gateways stateless — they just hold sockets and forward. Every message is written to the Message store and each recipient’s Inbox before any push, so nothing lives only in memory. Cross-server delivery rides pub/sub partitioned by user ID, so each gateway only subscribes to its own users. Order is server receipt time; in chat, fast beats perfectly ordered.

Avoid

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 either. One busy group would turn into a hot partition, so partition by user instead. And I would not add sharding layers before measuring the real per-partition message rate. Sharding too early adds failure modes, not capacity.

Change if

If end-to-end encryption comes into scope, the server can only be a blind router of ciphertext. Inbox and multi-device sync then move to per-device message copies and client-held keys.

03

Architecture path

One complete picture first, then each path as its own diagram — the write path and the read path carry different traffic and justify different components.

Complete picture

Overview — every component

Client(WebSocket)ConnectionGatewayMessage ServiceMessage + InboxStoreRecipientGatewaysPub/Sub (peruser)route to gatewaysConnectionRegistryuser → gateway lookupPushNotificationoffline devices

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.

Path 1

Send path — durable first, then fan out

Sender ClientGatewayMessage ServiceMessage + InboxStorePub/Sub →Gateways

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.

Path 2

Reconnect path — drain the inbox

Client(reconnect)GatewayInbox(undelivered)Message StoreClient synced

On reconnect the client drains its inbox and compares sequence numbers. Anything missed in transit is pulled, then real-time delivery resumes.

04

API and data model

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

Chat

chat_id (PK) · participants (≤100) · name

Message

message_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.

Inbox

user_id (PK) · message_id · ttl_30d

The durability backstop: written BEFORE any push attempt, drained on reconnect.

Client

user_id (PK) · client_id · last_seen

One user, several devices (~3 cap) — delivery is tracked per client, not per user.

05

Deep dive directions

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.

Focus

A hundred million open sockets

Ask

How do hundreds of millions of users hold persistent connections, and how does a message find the one gateway holding its recipient?

Answer

Each gateway holds ~1M sockets; a registry maps user → gateway, and pub/sub partitioned by user ID delivers each message only to the gateway that holds its recipient.

Avoid

Broadcasting every message to every gateway — subscribe gateways only to their own connected users.

Focus

The recipient is offline

Ask

Where does the message wait, for how long, and what happens the moment they reconnect?

Answer

It waits in the recipient's durable inbox with a 30-day TTL; on reconnect the client drains the backlog, and the push notification service nudges idle devices in the meantime.

Avoid

Relying on pub/sub for durability — it is at-most-once; the inbox write must come first.

Focus

Two phones, one account

Ask

A user reads a message on their laptop. What does their phone need to know, and how is per-device state tracked?

Answer

Delivery and read state are tracked per device, not per user; each device syncs from its own cursor, so the phone pulls exactly what it has not yet seen.

Avoid

Tracking delivery per user instead of per client — the second device silently misses messages.

Focus

Messages arrive out of order

Ask

Two messages race through different gateways. What order does the recipient see, and why is that acceptable?

Answer

Order is server receipt time per conversation, and clients render by that timestamp; a brief race between gateways is invisible in practice, while blocking for global order would cost latency users do notice.

Avoid

Blocking delivery to enforce global order — users prefer fast over perfectly sequenced.

Focus

A gateway dies mid-conversation

Ask

Ten thousand users drop at once. What do they lose, and how fast are they whole again?

Answer

Nothing is lost — undelivered messages live in durable inboxes, not gateway memory. Clients reconnect to another gateway, and the 10-30 s heartbeat carrying the latest sequence number lets each client spot its gap and pull what it missed.

Avoid

Any design where gateway memory is the only copy of an undelivered message.

Ready to practice?

Talk through Facebook Messenger out loud and get AI scoring on the explanation.

Practice this with AI →