Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

System Design · step by stepDesign WhatsApp
Step 1 / 10

Deep cut · 13:32

One message, one grey tick, one tunnel.

The interactive build above walks chat delivery step by step. The film follows a single message, Maya’s “I got the job!”, to her brother Sam on a train with no signal: why polling collapses, one open line per phone, a directory, a mailbox that holds the letter until the phone says got it, what each tick really is, order and once-only delivery, group fan-out, and the seal that stops the server reading a word.

  • See the numbers: 500,000,000 phones polling every 5 s is 100,000,000 asks a second, 99 in 100 of them empty. 100,000,000,000 messages a day is about 1.2 million a second.
  • The ticks: one message makes 4 packets (the message and three acknowledgments), about 4.6 million packets a second at that rate.
  • Take it into the interview: a mailbox deleted only on “got it”, a per-chat number and a message id for order and once-only, one upload fanned out to 999 group members, and an end-to-end seal.

The whole design, in writing

Every step of the build above, written out: the problem each piece solves, the option that was taken and the ones that were not, the numbers, and how it fails in production.

The big idea

What is WhatsApp, really?

Strip away the brand and WhatsApp does one magical thing: get a message from your phone to anyone else's — instantly, reliably, anywhere on Earth — and tell you the moment they've read it.

AliceBob
New in this step: Alice, Bob. · swipe to pan the diagram

That one sentence hides brutal questions. How do two phones that can't talk directly reach each other? What if the other person is offline? How do you do this for 2+ billion people at once — and prove delivery with those little ✓✓ ticks?

What the new pieces do

Alicealice
The sender. Types a message and expects it to reach Bob instantly — and to know the moment he's read it.
Bobbob
The receiver. Might be online, offline, or on another continent. The whole system exists to reach him.

Step 1 · The skeleton

Two phones, one server

Alice's phone and Bob's phone can't message each other directly — phones hide behind carrier networks, change IPs, and fall asleep. They need a middleman both can reach.

Relay ServerMessage Store
New in this step: Relay Server, Message Store. · swipe to pan the diagram

Two phones behind carrier networks, changing IPs, falling asleep — they can’t talk directly. How do they exchange messages?

  1. Rejected. Peer-to-peer: the phones connect directly to each other.

    Phones hide behind NAT/carrier networks, change IPs, and sleep — a direct connection rarely works and breaks constantly. You need a reliable middleman both can always reach.

  2. The call. A server in the middle that stores then forwards each message.

    Alice sends to the server, which holds a copy in a Message Store and forwards to Bob. Store-and-forward — holding each message until the recipient has it — is what lets messaging survive flaky networks and sleeping phones.

  3. Rejected. Email the message to the recipient.

    Email is slow, not real-time, and a different system. Chat needs an instant relay that tracks delivery — a server that stores and forwards.

Put a server in the middle. Alice sends her message to the server; it saves a copy in a Message Store and forwards it to Bob. The classic client → server → client relay — the spine of every chat app.

What the new pieces do

Relay Serverbackend
The single front door. Routes each message deeper into the system. Becomes an API Gateway + load balancer at scale.
Message Storestore
Durable storage holding a message only until it's delivered to every recipient — then it's gone. WhatsApp keeps no chat history.

Step 2 · Always-on

Reach Bob the instant it lands

The server is holding Alice's message — but Bob's phone isn't asking for it. Polling "any messages for me?" every second, for billions of phones, would melt the planet and still feel slow.

Relay ServerConnection ServerMessage Store
New in this step: Connection Server. · swipe to pan the diagram

The server holds Alice’s message, but Bob’s phone isn’t asking for it. How does it arrive instantly?

  1. Rejected. Bob’s phone polls "any messages for me?" every second.

    Billions of phones polling every second is a self-inflicted DDoS that still feels laggy (you wait a poll interval). The server should push the instant a message arrives.

  2. Rejected. Send Bob a push notification to open the app.

    Push notifications wake a closed app, but in-chat delivery needs a live two-way pipe for messages, typing and receipts — not a nudge to reopen. Keep a persistent connection while online.

  3. The call. A persistent WebSocket per phone; the server pushes on arrival.

    An always-open socket flips the model — the server speaks first, delivering the moment a message lands, with no polling. One warm pipe carries messages, typing dots and receipts both ways.

Keep a persistent connection — a WebSocket — open between every phone and a Connection Server. Now the server can push the moment a message arrives. No refreshing, no polling; the pipe stays warm as long as you're online.

What the new pieces do

Connection Serverrealtime
Holds a permanent open socket to each online phone, so the server can push a message the instant it arrives — no refreshing.

Step 3 · The address book

Which server is Bob on?

At scale there isn't one connection server — there are thousands. Alice's socket lands on server #14; Bob's on server #882. Server #14 holds the message but has no idea where Bob is.

Connection ServerWebSocketSession Servicewho's where
New in this step: Session Service.

There are thousands of connection servers. Alice is on #14, Bob on #882. How does #14 deliver to Bob?

  1. Rejected. Server #14 broadcasts the message to all connection servers.

    Shouting to thousands of servers per message is hugely wasteful and doesn’t scale. You want to deliver to exactly one place — the server holding Bob’s socket.

  2. The call. A Session Service maps user → connection server; look Bob up and route.

    When Bob connects he registers his spot; to deliver, #14 asks "where’s Bob?", finds #882, and routes straight there. Service discovery turns "shout to everyone" into "deliver to exactly one place" — a fast in-memory registry (Redis).

  3. Rejected. Pin every user to a fixed connection server forever.

    Phones roam, reconnect and load-balance across servers constantly, so a fixed assignment breaks the moment Bob reconnects elsewhere. The registry must update on every connect/disconnect.

A Session Service keeps a live registry: user → connection server. When Bob connects he registers his spot. To deliver, server #14 asks "where's Bob?", finds server #882, and routes the message straight there.

What the new pieces do

Session Serviceregistry
A registry mapping each online user to the exact connection server holding their socket — so a message knows where to go.

Step 4 · When Bob's asleep

Deliver to someone offline

Bob's phone is off, or he's on the subway with no signal. There's no socket to push to. The message can't just vanish — and Alice shouldn't have to wait or retry.

Connection ServerWebSocketInbox Queueper user
New in this step: Inbox Queue.

Bob’s phone is off or has no signal — there’s no socket to push to. What happens to the message?

  1. Rejected. Alice’s phone keeps retrying until Bob comes online.

    Making the sender retry for hours/days drains Alice’s battery and blocks her on a sleeping recipient. The server should absorb the wait, not the sender.

  2. Rejected. Drop the message and ask Alice to resend later.

    Silently dropping messages is unacceptable — delivery must be reliable. The message has to be held safely until Bob reappears.

  3. The call. Queue it in Bob’s per-user Inbox Queue; drain on reconnect, then delete.

    If the registry shows no live connection, the message waits in Bob’s mailbox; the moment he reconnects the server drains the queue to his phone, confirms delivery, and deletes the stored copy. The queue decouples send from receive.

If the registry shows Bob has no live connection, drop the message into his Inbox Queue — a per-user mailbox. The moment Bob reconnects, the Connection Server drains his queue to the phone, confirms delivery, and the stored copy is deleted.

  • 100B+messages / day
  • 2B+users
  • daysa queue can wait

What the new pieces do

Inbox Queuequeue
When the recipient is offline, the message waits here. On reconnect the queue drains to their device, then the copy is deleted.

Back of the envelope

no live socket ⇒ Inbox Queue
the server absorbs the wait, not the sender
queue waits seconds…days
drains on reconnect, then deletes
100B+ msgs/day, 2B+ users
most delivered live, the rest queued

Step 5 · The famous ticks

✓ sent, ✓✓ delivered, ✓✓ read

Alice wants to know what happened to her message. Did it leave her phone? Reach Bob's? Did he actually read it? Silence breeds anxiety.

AliceBobRelay ServerConnection ServerSession ServiceInbox QueueMessage Store
The system as it stands at this step. · swipe to pan the diagram

Every hop sends a tiny acknowledgement back. Reaches the server → one ✓. Delivered to Bob's device → two ✓✓. Bob opens the chat → his phone reports it and the ticks turn blue. A little state machine riding the same socket.

Step 6 · Group chat

One message, many phones

Alice posts in a 50-person group. We can't make her phone send 50 copies — that's slow and drains her battery. But everyone must get it, in order.

Connection ServerWebSocketInbox Queueper userMessage Storeuntil deliveredGroup Servicefan-out
New in this step: Group Service.

Alice posts in a 50-person group. How does everyone get it, in order, without her phone sending 50 copies?

  1. The call. She sends one message; a Group Service fans it out to each member.

    One message tagged with the group id; the Group Service looks up members and fans out a copy to each one’s connection (or Inbox Queue if offline). One send in, N deliveries out, all server-side — fan-out on write.

  2. Rejected. Her phone sends a copy directly to all 50 members.

    Client-side fan-out is slow and drains her battery, and her phone doesn’t know everyone’s connection server. Fan-out belongs on the server, which knows where each member is.

  3. Rejected. Everyone polls a shared group inbox for new messages.

    Polling a shared inbox reintroduces the lag and load you removed with push, and complicates per-member delivery/receipts. Push a fanned-out copy to each member instead.

She sends one message tagged with the group id. A Group Service looks up the members and fans out a copy to each one's connection — or their Inbox Queue if offline. One send in, N deliveries out, all handled server-side.

What the new pieces do

Group Serviceservice
Expands a group into its member list and fans the message out — one send becomes N deliveries.

Step 7 · Photos & video

Don't push a video down the socket

A 50 MB video can't ride the same lightweight pipe as "lol 😂". Pushing big blobs through connection servers would clog the real-time path for everyone.

Relay ServerConnection ServerInbox QueueMessage StoreGroup ServiceBlob + CDN
New in this step: Blob + CDN. · swipe to pan the diagram

A 50 MB video can’t ride the same lightweight pipe as "lol 😂". How do you send media?

  1. Rejected. Stream the video through the connection server like a big message.

    Pushing big blobs through the real-time connection servers clogs the messaging path for everyone. Text and media need different roads.

  2. Rejected. Split the video into chunks and send them as many chat messages.

    Cramming a video into the message pipeline as chunks still loads the real-time path and the message store with huge data. Media should bypass the chat pipeline entirely.

  3. The call. Upload once to blob storage + CDN; the chat carries a pointer + thumbnail + key.

    Media uploads once to blob storage fronted by a CDN near each viewer; the message carries only a small pointer, thumbnail and decryption key, and Bob fetches the blob from the nearest edge. Separate the data plane from the control plane.

Upload media once to blob storage, fronted by a CDN that caches it near each viewer. The chat message carries only a small pointer + thumbnail + decryption key. Bob's phone fetches the blob straight from the nearest CDN edge.

What the new pieces do

Blob + CDNstore
Photos and videos skip the message pipeline: uploaded once to blob storage, cached on a CDN near you, shared as a link + thumbnail.

Back of the envelope

50 MB video ≠ "lol 😂"
different roads: CDN vs the socket
upload once ⇒ blob + CDN
cached near each viewer
chat carries pointer + thumb + key
tiny control message, big data elsewhere

Step 8 · Trust & scale

2 billion phones, zero peeking

Two hard problems at once: how do a handful of servers hold billions of live connections — and how do you promise that not even WhatsApp can read people's messages?

Connection ServerWebSocketPresenceonline · typing
New in this step: Presence.

Connection servers are tuned to hold ~2 million sockets each, so a modest fleet covers the planet; Presence rides the same socket via heartbeats. And every message is end-to-end encrypted — the server only ever relays ciphertext it cannot decrypt.

  • ~2Msockets / server
  • 256-bitE2E keys
  • 0msgs server can read

What the new pieces do

Presenceservice
Tracks who's online, last-seen and typing — using lightweight heartbeats over the same socket.

Back of the envelope

~2M sockets per server
a modest fleet covers the planet
E2E: keys live on devices only
the server relays sealed ciphertext
0 messages the server can read
privacy by design, not promise

You did it

You just designed WhatsApp.

AliceBobRelay ServerConnection ServerSession ServiceInbox QueueMessage StoreGroup ServiceBlob + CDNPresence
The finished design, end to end. · swipe to pan the diagram

Everything you assembled, in order

  • Store-and-forward server — the relay spine between two phones.
  • Persistent WebSockets so the server pushes messages instantly.
  • A Session registry routes each message to the right connection server.
  • Per-user Inbox Queues hold messages for offline recipients.
  • Acknowledgements drive the ✓ / ✓✓ / blue-tick delivery receipts.
  • A Group Service fans one message out to every member.
  • Media via blob storage + CDN; only a tiny pointer rides the chat.
  • ~2M sockets per server and end-to-end encryption at planet scale.

Where an interviewer pokes next

Getting the boxes right is the easy half. These are the questions that separate a candidate who drew the diagram from one who has run the thing.

  1. How does end-to-end encryption work if the server routes everything?

    Each device holds its own keys; the sender encrypts with the recipient’s public key (WhatsApp uses the Signal protocol — X3DH key agreement + the Double Ratchet for forward secrecy) so the server only stores and forwards sealed ciphertext it mathematically cannot open. It routes perfectly (it sees who-to-whom and timing metadata) while being unable to read content. Key changes surface as the “security code changed” notice.

  2. Does WhatsApp store your chat history on its servers?

    No — a message is stored only until it’s delivered to every recipient, then deleted. That’s deliberate (a privacy and cost win): the phones are the source of truth for history, and backups are the user’s responsibility (their own cloud). The server’s job is reliable relay, not archival — which is why the Message Store and Inbox Queue are transient, not a chat database.

  3. How do the ✓ / ✓✓ / blue ticks actually work?

    They’re the visible edge of an acknowledgement protocol. One ✓ = the server received it; ✓✓ = delivered to the recipient’s device (their phone ACKed); blue ✓✓ = they opened the chat and their phone sent a read receipt. Each ACK rides the same socket back to the sender — a small per-message state machine (sent → delivered → read) and the reason no message is silently lost.

  4. Why fan out groups on write, and where does that break?

    Fan-out on write copies a group message to each member’s connection/queue the instant it lands, keeping delivery fast for the small-to-medium groups WhatsApp is tuned for. It breaks for very large groups (thousands of members): one message becomes thousands of deliveries and encryptions — a fan-out storm. That’s why huge-broadcast use-cases use Channels/Broadcast (a different, pull-leaning model) rather than ordinary group fan-out.

  5. How does a handful of servers hold billions of connections?

    Each connection server is tuned to hold on the order of ~2 million simultaneous sockets (famously on Erlang with a tiny team), so a modest fleet covers billions of users. Sockets are mostly idle — a phone sends a few bytes occasionally — so the constraint is memory per connection and efficient event handling, not CPU. Presence and typing ride the same socket as heartbeats, avoiding extra connections.

Check yourself — the answers, and why

Nine steps in, these are the calls you should be able to make cold. Each answer carries its reasoning.

  1. The server "stores and forwards" so that…

    • Messages send faster
    • Messages survive flaky networks and sleeping phones
    • It can read them

    It holds each message until the recipient has it — the spine of reliable messaging.

  2. Messages arrive instantly because of…

    • Fast polling
    • A persistent WebSocket the server pushes over
    • Email

    An always-open socket lets the server speak first, delivering the moment a message lands.

  3. To route Alice→Bob across thousands of servers, the system uses…

    • A broadcast to all servers
    • A Session registry mapping user → connection server
    • A fixed server per user

    Service discovery turns "shout to everyone" into "deliver to exactly one place."

  4. When Bob is offline, his message…

    • Is dropped
    • Waits in his per-user Inbox Queue, draining on reconnect
    • Bounces to Alice

    A queue decouples send from receive; the sender never blocks on a sleeping recipient.

  5. End-to-end encryption means the server…

    • Encrypts messages for you
    • Only ever relays ciphertext it cannot read
    • Stores your keys

    Keys live on devices; the server routes sealed envelopes it’s mathematically unable to open.

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

What it must do

Agree on these before drawing a single box.

  • Send 1:1: Alice sends a message to Bob and it reaches him — whether he is online, offline, or on another continent.
  • Deliver live: when Bob is connected the message lands in milliseconds, pushed rather than polled for.
  • Survive offline: if Bob is unreachable the message waits, and drains the moment he reconnects.
  • Receipts: ✓ sent, ✓✓ delivered, blue ✓✓ read — each tick backed by a real acknowledgement.
  • Groups: one message from one sender reaches every member of a group.
  • Media: photos and video attach to a chat without being pushed down the message socket.
  • End-to-end encryption: only the participating devices can read a message — the servers relaying it cannot.

The qualities that shape everything

Each one names the mechanism that buys it.

A message is never lost, even to a phone that is off
The relay stores each message before forwarding it, and an unreachable recipient gets a per-user Inbox Queue that holds the message until reconnect. Store-and-forward is what makes messaging survive flaky networks and sleeping phones.
Delivery feels instant, not polled
Each phone holds a persistent WebSocket to a Connection Server, so the server pushes the moment a message arrives rather than waiting for the client to ask. Polling would put a lag floor under every message.
Find the right server out of thousands
A Session Service maps user → the connection server currently holding their socket, so “deliver to Bob” becomes one lookup and one push, not a broadcast to every server.
The ticks mean something
Each tick is a distinct acknowledgement travelling back: the server confirms receipt (✓), the recipient device confirms delivery (✓✓), and the recipient app confirms the chat was opened (blue ✓✓). The UI is the visible edge of an ack protocol.
A group message does not melt the sender
The sender uploads one message; the server fans it out to each member’s connection or queue. Fan-out happens once, server-side, so the sender’s phone pays for one send regardless of group size.
A video does not block the chat
Media goes out-of-band — the client uploads to a blob store and sends only a reference over the socket, so a large upload never occupies the path that ordinary messages travel.
The operator cannot read messages
Keys live on the devices. The sender encrypts for the recipient’s device and the servers relay ciphertext they have no key for, so “trust us” is replaced by “we are unable to”.
Billions of phones on a modest fleet
Connections are cheap when they are idle — each connection server is tuned to hold on the order of ~2 million open sockets, so the fleet is sized by concurrent connections rather than by registered users.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

A relay that stores then forwards over phones connecting directly to each other

Phones sit behind carrier NAT, change IP as they move, and sleep to save battery — a direct connection rarely establishes and constantly breaks. A middleman both sides can always reach is also the only place a message can wait while one side is offline.

A persistent WebSocket the server pushes over over the client polling for new messages

Polling puts a floor under latency and wastes most requests returning nothing. Holding an idle socket costs memory but almost no CPU, so pushing is both faster and cheaper at this scale.

A session registry over asking every connection server whether it holds the recipient

A broadcast is O(servers) work for every single message and couples every server to every other. One registry lookup turns routing into a constant-cost step and lets you add servers without rewiring anything.

Deleting a message once delivered over keeping chat history on the server

Server-side history would make multi-device sync and restore trivial — and would also make the servers a target worth attacking and a subpoena worth serving. Holding a message only until it is delivered means there is little to hand over.

Fan-out on write for groups over each member pulling the group’s messages

Push keeps delivery uniform: a group message travels the same path as a 1:1 one and arrives without the recipient asking. The cost is N queue writes per message, which is why group size is capped rather than unbounded.

Media out-of-band via a blob store over sending bytes over the message socket

The socket is shared by every message on that connection; a 60 MB video would occupy it for seconds and delay everything behind it. Uploading separately and sending a reference keeps the message path small and predictable.

End-to-end encryption over server-side plaintext

Plaintext on the server would enable search, cloud history and server-side spam filtering. Encrypting end to end gives those up in exchange for a guarantee that survives a breach or a legal order — for a messenger, that guarantee is the product.

What this teaches

How a message gets from one phone to another when neither can be reached directly: store-and-forward through a relay, a persistent socket so delivery is a push rather than a poll, a registry that says which server holds the recipient, a per-user queue for when nobody is home, and an acknowledgement protocol that turns all of it into two grey ticks and one blue pair.

Key takeaways

  • Store-and-forward server — the relay spine between two phones.
  • Persistent WebSockets so the server pushes messages instantly.
  • A Session registry routes each message to the right connection server.
  • Per-user Inbox Queues hold messages for offline recipients.
  • Acknowledgements drive the ✓ / ✓✓ / blue-tick delivery receipts.
  • A Group Service fans one message out to every member.
  • Media via blob storage + CDN; only a tiny pointer rides the chat.
  • ~2M sockets per server and end-to-end encryption at planet scale.

Concepts covered

  • What is WhatsApp, really?
  • Two phones, one server
  • Reach Bob the instant it lands
  • Which server is Bob on?
  • Deliver to someone offline
  • ✓ sent, ✓✓ delivered, ✓✓ read
  • One message, many phones
  • Don't push a video down the socket
  • 2 billion phones, zero peeking
built to be read, not memorized — hover the boxes, send a message, watch the ticks turn blue.
Finished this one? 0 / 65 System Designs done
NextDesign a Notification System Next in “System Design in 30 Days” · step 14 of 21

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More System Designs