Design a chat app
Requirements and numbers
The app needs 1:1 chats, group chats, and online status. Every message must arrive, even to someone offline, in the same order for everyone. Say 50 million people a day send 40 messages each: 2 billion a day, about 23,000 a second. Messages must show up at once, so the server pushes them.
Connection servers
Each phone keeps a WebSocket open to a connection server. A shared session store records which server each user is on. To reach Bob, server 1 looks him up and passes the message through pub/sub to server 3, which pushes it to Bob. Phones send a heartbeat every few seconds; when heartbeats stop, the user is shown offline.
Storing and ordering messages
Every message is saved before it is delivered. Each chat hands out its own sequence numbers (1, 2, 3) from one place, so no two messages share one. Don't sort by clock times: machine clocks drift. Split messages across machines by chat ID, keeping each chat together.
Offline delivery
If Bob is offline, the server sends a push notification through Apple or Google. When Bob reconnects, his app says "my last message in chat 9 is 37" and gets the rest. Push can be late or lost; this sync makes delivery sure. Alice sees sent once the server saves it, delivered once it reaches Bob's phone, and read once Bob opens the chat.
Group fan-out
A group message must reach every member: this is fan-out. A group is one chat, so the server saves the message once, with the group's next number. Then it gets the member list and publishes the message to each online member's connection server. Each server pushes it to its users; offline members get a push and sync later. Work grows with group size, so apps cap it.
Remember
- A shared store says which connection server each user is on.
- Save every message first.
- Order by a sequence number per chat, not by clocks.
- Offline: push notification, then sync after the last number.
- Group: one message, sent to every member's server.