Design WhatsApp: Real-Time Messaging for 2 Billion Users
SD
ScaleDojo
May 11, 2026
2 min read463 words
55 Engineers, 2 Billion Users
WhatsApp served 1 billion users with just 55 engineers. Their secret weapon was Erlang - a programming language built for telecom systems that handles massive concurrency with minimal resources. A single Erlang server handled 2 million simultaneous connections, compared to ~10,000 for a typical Node.js server. When Facebook acquired WhatsApp for $19 billion in 2014, this tiny team was processing 50 billion messages per day.
Message Delivery Flow
Message Delivery (Alice sends to Bob):
[Alice's Phone]
|
1. Send message via persistent WebSocket
{msg_id: uuid, to: bob, body: encrypted_text}
|
[Chat Server A] (Alice is connected here)
|
2. Store in Cassandra (durability)
Partition key: recipient_id
Clustering key: timestamp
|
3. Lookup Bob's connection:
[Presence Service - Redis]
bob -> {server: chat_server_B, last_seen: 14:30:01}
|
+-----+------+
| |
Bob ONLINE Bob OFFLINE
| |
4a. Forward 4b. Message stays
to Server B in Cassandra
| (offline queue)
Push via |
WebSocket When Bob connects:
| Fetch all pending
5. Bob's messages from Cassandra
phone sends (FIFO by timestamp)
delivery ACK
|
6. Update status: sent -> delivered -> read
(double blue ticks)
Group Messages: The Write Amplification Problem
Group Message Fan-out:
Alice sends to group 'Family' (50 members)
|
[Chat Server]
|
Write to Cassandra ONCE (group_messages table)
|
Fan-out to 50 members:
For each member:
- Online? Push via their WebSocket
- Offline? Mark unread in their inbox
|
Scale impact:
Max group size: 1024 members
50B messages/day, 40% are groups (avg 20 members)
Group fan-out: 20B * 20 = 400B delivery operations/day
This is why Cassandra (not PostgreSQL):
400B writes/day = 4.6M writes/sec
Cassandra scales linearly by adding nodes
100 nodes * 50K writes/sec each = 5M writes/sec
Connection Architecture
Connection Efficiency (Why Erlang):
Technology Connections/Server Memory/Connection
───────────── ─────────────── ─────────────────
Erlang (BEAM) 2,000,000 ~300 bytes/process
Go goroutines 500,000 ~8 KB/goroutine
Java threads 10,000-50,000 ~1 MB/thread
Node.js 10,000-50,000 ~10 KB/connection
2 billion users online at peak:
With Erlang: 2B / 2M = 1,000 servers
With Java: 2B / 50K = 40,000 servers
This is why 55 engineers could run WhatsApp.
Fewer servers = fewer ops people needed.
Interview Tip
When designing a chat system, cover three pillars: (1) persistent WebSocket connections with a presence service (Redis mapping user to server), (2) message storage for offline delivery (Cassandra partitioned by recipient for fast inbox queries), (3) delivery receipts flowing back through the same path. For groups, emphasize write amplification and why Cassandra's linear horizontal scaling handles it. Mention Erlang/Go for connection density if asked about technology choices.
<Architecture overview
/blockquote>
Key Takeaway
Chat systems need persistent connections (WebSockets), a presence service (who is connected where), message storage for offline delivery (Cassandra), and fan-out for groups. Erlang's actor model enabled WhatsApp to handle unprecedented connection density with a tiny team.
No comments yet. Be the first to start the thread!
Related Articles
Enjoyed this content?
Your support keeps us creating free resources
We put a lot of hours into researching and writing these guides. If it helped you, consider buying us a coffee. Every bit goes toward keeping ScaleDojo's content free and growing.
$
One-time payment via Stripe. ScaleDojo account required.