Lesson 21 / 25

Design a Chat System

Persistent connections and ordering.

WebSockets, routing and storage

Clients keep WebSocket connections to stateful chat servers; a presence and routing service records which server holds each user's connection. Sending a message: persist it (a wide-column store partitioned by conversation and ordered by a time-sortable message ID), then route it to recipients' servers through a pub/sub layer, or queue a push notification if they are offline. Group chats fan out to members; delivery and read receipts are additional small messages.

Message flow (sketch)

A design sketch, not a running system.

sender --ws--> chat server A
  1. assign message_id (time-sortable), persist to messages(conversation_id, message_id)
  2. ack to sender ("sent")
  3. look up recipient connection in presence service
       online  -> publish to chat server B --ws--> recipient -> "delivered" receipt
       offline -> enqueue push notification; recipient syncs from storage on reconnect
  sync on reconnect: GET messages WHERE conversation_id=? AND message_id > last_seen

Order within a conversation, not globally

Per-conversation ordering with time-sortable IDs is enough and far easier than global ordering.

Quick check: Why do chat systems usually use WebSockets?

  • They compress images
  • They keep a persistent two-way connection so servers can push messages instantly
  • They replace databases
  • They avoid needing servers
Answer

They keep a persistent two-way connection so servers can push messages instantly — Server push without polling.