Design a Chat System
2 min read
Design a Chat System (WhatsApp / Discord)
1. Requirements
- Functional: 1:1 and group messages; online status; delivery & read receipts; history.
- Non-functional: low latency (< 100 ms), highly available, ordered per conversation, durable.
2. The core challenge: real-time delivery
HTTP is request/response — the server can't initiate. Options:
| Technique | How | Verdict |
|---|---|---|
| Polling | Client asks repeatedly | Wasteful |
| Long polling | Hold the request open | Better |
| WebSocket | Persistent, bidirectional | ✅ The standard |
Clients hold an open WebSocket to a gateway service that tracks which user is on which server.
3. High-level design
User A ══ws══▶ Gateway 1 ─▶ Message service ─▶ DB (persist)
▼
User B ◀══ws══ Gateway 2 ◀── routed via presence registry
- Presence registry (Redis):
user_id → gateway_server. To deliver, look up B's server and forward. - If B is offline: persist the message; deliver on reconnect + push notification.
4. Data model
messages: id | conversation_id | sender_id | content | created_at | status
(partition by conversation_id; sort by created_at)
Use a write-optimised store (Cassandra) — chat is write-heavy and append-only.
5. Deep dives
- Ordering: a monotonic sequence per conversation keeps render order correct.
- Receipts:
sent → delivered → read, each an ack event. - Group chat: fan-out to each member's connection.
Takeaway: the heart of a chat system is persistent connections + a presence registry to route messages in real time.