100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

How Would You Design a WhatsApp-Style Chat System?

Learn how to design a WhatsApp-style chat system: persistent connections, presence routing, message ordering, and offline delivery.

hardQ27 of 224 in System Design Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

A WhatsApp-style chat system is built around persistent WebSocket connections held open by connection-gateway servers, a message service that durably stores and routes each message to the recipient’s connected gateway (or queues it for delivery when they are offline), and per-conversation message ordering guaranteed by a monotonically increasing sequence id.

Each client maintains a long-lived WebSocket (or similar persistent connection) to one of many stateless connection-gateway servers behind a load balancer; a presence service tracks which gateway instance currently holds each user’s connection. When user A sends a message to user B, it is written durably to a message store keyed by conversation id, assigned a sequence number for ordering, and then the routing layer looks up which gateway (if any) holds B’s live connection and pushes the message directly; if B is offline, the message waits in their inbox and is delivered (or fetched) on reconnect. Delivery and read receipts are separate lightweight events layered on top of the same pipeline. End-to-end encryption means the server only ever routes opaque ciphertext, and group chats fan out the same message to every member’s connection much like a mini broadcast.

  • Persistent connections give near-instant delivery without client polling overhead
  • A durable message store with per-conversation sequencing handles offline recipients and ordering correctly
  • Stateless gateway servers with a presence lookup allow horizontal scaling of connection capacity
  • Separating delivery/read receipts from the core message write keeps the critical path fast

AI Mentor Explanation

A chat system is like a stadium radio channel where each fielder keeps an open earpiece to the captain instead of the captain shouting and hoping it is heard — that open earpiece is the persistent connection. A dugout log records every instruction in order with a sequence number, so even if a fielder’s earpiece cuts out, the instruction waits there and is replayed once they reconnect. The captain’s coordinator tracks exactly which channel each fielder is currently tuned to, mirroring a presence service routing to the right gateway. Read and delivery confirmations are simple separate pings layered on top, not part of the core instruction itself.

Step-by-Step Explanation

  1. Step 1

    Establish a persistent connection

    Each client opens a long-lived WebSocket to a stateless gateway server behind a load balancer; presence records which gateway holds each user.

  2. Step 2

    Write the message durably

    The message is written to a per-conversation message store and assigned a monotonically increasing sequence number for ordering.

  3. Step 3

    Route to the recipient

    The routing layer looks up the recipient’s current gateway via presence and pushes the message; if offline, it waits in their inbox.

  4. Step 4

    Emit delivery and read receipts

    Lightweight receipt events are layered on top of the core pipeline once the client acknowledges delivery or the message is read.

What Interviewer Expects

  • Describes persistent connections (WebSocket) and a stateless gateway + presence layer for routing
  • Explains durable storage with per-conversation sequencing for correct ordering and offline delivery
  • Separates delivery/read receipts from the core message write path
  • Mentions group chat fan-out and end-to-end encryption implications on the server’s role

Common Mistakes

  • Proposing client polling instead of persistent connections for real-time delivery
  • Ignoring offline recipients and how queued messages get delivered on reconnect
  • Forgetting per-conversation ordering guarantees, causing out-of-order message display
  • Coupling read/delivery receipts tightly into the same write path as the core message

Best Answer (HR Friendly)

A chat app like WhatsApp keeps your phone connected to a server the whole time you have the app open, so messages can be pushed to you instantly instead of your phone having to keep asking “any new messages?” If you are offline, the message just waits safely on the server until you reconnect, and the system keeps careful track of the order messages were sent in so conversations always display correctly.

Code Example

Message send and routing (simplified)
async function sendMessage(conversationId, senderId, recipientId, ciphertext) {
  const seq = await messageStore.nextSequence(conversationId)
  const message = await messageStore.append(conversationId, {
    senderId,
    ciphertext,
    seq,
    sentAt: Date.now(),
  })

  const gatewayId = await presence.lookupGateway(recipientId)
  if (gatewayId) {
    await gatewayCluster.push(gatewayId, recipientId, message) // online: instant push
  } else {
    await inbox.enqueue(recipientId, message) // offline: delivered on reconnect
  }

  return message
}

async function onClientReconnect(userId, gatewayId) {
  await presence.setGateway(userId, gatewayId)
  const pending = await inbox.drain(userId)
  for (const msg of pending) {
    await gatewayCluster.push(gatewayId, userId, msg)
  }
}

Follow-up Questions

  • How would you guarantee message ordering across a group chat with many senders?
  • How does presence routing scale when a user’s connection can be on any of thousands of gateway instances?
  • How would you implement end-to-end encryption while still allowing group fan-out?
  • What happens to delivery guarantees if the gateway holding a connection crashes mid-push?

MCQ Practice

1. Why do chat systems use persistent WebSocket connections instead of client polling?

A persistent connection lets the server push messages the instant they arrive, avoiding the latency and overhead of repeated polling requests.

2. What is the role of the presence service in a chat system?

Presence maps each online user to the specific gateway instance holding their connection, which the routing layer uses to deliver messages.

3. What happens to a message if the recipient is offline when it is sent?

Offline messages are held durably in the recipient’s inbox and pushed once presence detects the user reconnecting to a gateway.

Flash Cards

Why persistent connections for chat?They allow instant server push without the latency/overhead of client polling.

What does the presence service track?Which gateway server currently holds each online user’s live connection.

How is message ordering guaranteed?A monotonically increasing sequence number per conversation.

What happens when the recipient is offline?The message is stored durably and delivered from the inbox on reconnect.

1 / 4

Continue Learning