Lesson 28 / 32
Design a Chat Application
Real-time delivery, presence, and message history at scale.
Requirements
1:1 and group messaging, delivery within ~100ms when online, offline users get messages on reconnect, message history, online/typing indicators. Assume 50M DAU sending 40 messages/day each.
Connection layer
Clients hold a persistent WebSocket to a connection-gateway server. A registry (Redis) maps user_id -> gateway server so any backend can find where to push a message. Sending to an offline user just writes to their inbox for later delivery.
Message flow
Write path: persist the message, then fan out to the recipient's active connection if online.
send(msg):
db.append(conversation_id, msg) # source of truth
gw = registry.lookup(recipient_id)
if gw: gw.push(msg) # online
else: queue.push(offline_inbox) # deliver on reconnect
Output:
DB write is the durability guarantee; push is best-effort
Order and dedupe with a sequence number
Assign each message a per-conversation sequence number so clients can detect gaps (fetch missing) and dedupe retried sends — network hiccups shouldn't reorder or duplicate what the user sees.