Design a chat system
Deliver messages in real time, in order, to users who come and go.
- Choose a real-time transport and route messages between connection servers.
- Order messages within a conversation with sequence numbers.
- Deliver to offline users and track presence.
Requirements. One-to-one and small group chats, real-time delivery, message history across devices, online presence, and delivery to users who are offline. Non-functional: low latency, messages must never be lost once acknowledged, and ordering must be consistent within a conversation.
Connections, routing, and storage
- Transport: clients hold a persistent WebSocket so the server can push messages instantly. Long polling is a fallback.
- Stateful gateways: WebSocket servers keep connections open, so they are stateful. A session registry (for example in Redis) maps each online user to the gateway holding their connection. Keep business logic in separate stateless services.
- Routing: the chat service persists the message, looks up each recipient’s gateway, and publishes to it (via pub/sub). Offline recipients get a push notification.
- Storage: messages are partitioned by
conversation_idand ordered by a per-conversation sequence number - a natural fit for a wide-column store.
1received = [1, 2, 4, 5]
2expected = range(received[0], received[-1] + 1)
3missing = [seq for seq in expected if seq not in received]
4print("missing:", missing)missing: [3]
Sequence numbers let clients detect gaps, as the demo shows, and sync on reconnect by asking for “messages after sequence N.” The server assigns them, because client clocks disagree. The server stores a message before acknowledging it to the sender, so an acknowledged message survives a crash. Presence uses heartbeats: a user who misses several heartbeats is marked offline. For group chats, the service fans each message out to every member’s gateway.
Key takeaways
Persistent connections make gateways stateful; a registry maps users to gateways.
Store before acknowledging, and order by server-assigned sequence numbers.
Offline users get push notifications and sync missed messages on reconnect.
Lesson quiz
6 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: simulate system design building blocks
Use small Python programs to estimate capacity and simulate caches, load balancers, hash rings, and rate limiters. These exercises run locally in your browser.
Sync missed messages
Read the last sequence number the client has seen, then a line of seq:text messages from the server in any order. Print every message with a higher sequence number as seq: text, in sequence order. If there are none, print no new messages. Finally print synced to N, where N is the highest sequence number now known to the client.
- Two missed messages
- Already up to date
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…