01

Requirements & scope

Problem Statement & Requirements

Functional Requirements

  • 1:1 messaging — send and receive text messages between two users in real-time
  • Group messaging — support group chats with up to 500 members (Slack-style) or 1024 (WhatsApp-style)
  • Online/offline presence — show whether a user is online, offline, or "last seen"
  • Message delivery status — sent, delivered, read (double/blue checkmarks)
  • Push notifications — notify offline users of new messages
  • Media sharing — images, videos, documents (up to 100 MB)
  • Message history — persistent storage, searchable, sync across devices
  • End-to-end encryption (E2E) — messages encrypted on sender, decrypted only by recipient

Non-Functional Requirements

  • Low latency — message delivery < 100 ms (same region), < 300 ms (cross-region)
  • High availability — 99.99% uptime (< 52 min downtime/year)
  • Ordering — messages within a conversation must be displayed in order
  • Durability — no message loss once server acknowledges
  • Scalability — support 500M+ daily active users, 100B+ messages/day
  • Multi-device sync — seamless experience across phone, web, desktop

Out of Scope

  • Voice/video calling (that's a separate WebRTC design)
  • Stories/status updates
  • Payment integration
  • Bots / slash commands (Slack-specific)
02

Scale estimations

Scale Estimations

Users & Traffic

Metric Value
Daily Active Users (DAU) 500M
Average messages sent per user per day 40
Total messages per day 500M × 40 = 20B
Messages per second (avg) 20B / 86400 = ~231K msg/s
Peak messages per second ~700K msg/s (3x average)
Average concurrent connections ~150M (30% of DAU)

Message Sizes

Metric Value
Average text message 200 bytes
With metadata (sender, timestamp, IDs, status) 500 bytes
Media messages (pointer only, media stored separately) 500 bytes + media URL
Average message with encryption overhead ~600 bytes

Storage

Metric Value
Text storage per day 20B × 600 bytes = ~12 TB/day
Text storage per year 12 TB × 365 = ~4.4 PB/year
Media storage per day (20% of messages have media) 4B × 500 KB avg = ~2 PB/day
Retention Text: forever; Media: configurable

Network

Metric Value
Incoming bandwidth (messages) 231K × 600 bytes = ~139 MB/s
Outgoing bandwidth (fan-out) ~278 MB/s (avg 2 recipients per msg including 1:1)
WebSocket connections (concurrent) ~150M
WebSocket servers needed (50K conn/server) ~3,000 servers
03

Layered architecture

High-Level Architecture

High-Level ArchitectureExcalidraw diagram · editable shapes · reveal step by stepExplore

Detailed Component Architecture

Detailed Component ArchitectureExcalidraw diagram · editable shapes · reveal step by stepExplore
04

API & contracts

Communication Protocol — WebSocket Deep Dive

Why WebSocket Over HTTP?

Why WebSocket Over HTTP?Excalidraw diagram · editable shapes · reveal step by stepExplore

WebSocket Connection Lifecycle

WebSocket Connection LifecycleExcalidraw diagram · editable shapes · reveal step by stepExplore
05

Data model

Data Model

Message Table (Cassandra)

Message Table (Cassandra)Excalidraw diagram · editable shapes · reveal step by stepExplore

Conversation Table

Conversation TableExcalidraw diagram · editable shapes · reveal step by stepExplore

User Conversation Index (for "list my chats")

User Conversation Index (for "list my chats")Excalidraw diagram · editable shapes · reveal step by stepExplore
06

Core design decisions

Message Ordering & IDs

Why Not Auto-Increment IDs?

Why Not Auto-Increment IDs?Excalidraw diagram · editable shapes · reveal step by stepExplore

Message Ordering Guarantee

Message Ordering GuaranteeExcalidraw diagram · editable shapes · reveal step by stepExplore
07

Request flows

Message Flow Diagrams

1:1 Message — Both Users Online

1:1 Message — Both Users OnlineExcalidraw diagram · editable shapes · reveal step by stepExplore

1:1 Message — Recipient Offline

1:1 Message — Recipient OfflineExcalidraw diagram · editable shapes · reveal step by stepExplore

Group Message Flow

Group Message FlowExcalidraw diagram · editable shapes · reveal step by stepExplore
08

Performance & caching

Workshop note · added for the website’s common reading format

Start with the dominant access pattern of Chat System. Message queue is one place to inspect capacity and tail latency. Measure before introducing a cache: define the cache key, invalidation policy, stale-data budget, and cold-start behavior.

Batch independent work where the latency budget allows it. Bound queues and concurrency, and verify that an optimization does not move the bottleneck to a dependency.

09

Advanced design

Presence (Online/Offline Status)

Presence Architecture

Presence ArchitectureExcalidraw diagram · editable shapes · reveal step by stepExplore

Presence at Scale — The Problem

Presence at Scale — The ProblemExcalidraw diagram · editable shapes · reveal step by stepExplore

End-to-End Encryption (E2E)

Signal Protocol (used by WhatsApp)

Signal Protocol (used by WhatsApp)Excalidraw diagram · editable shapes · reveal step by stepExplore

E2E Encryption Flow

E2E Encryption FlowExcalidraw diagram · editable shapes · reveal step by stepExplore

Group E2E Encryption

Group E2E EncryptionExcalidraw diagram · editable shapes · reveal step by stepExplore

Message Queue & Delivery Guarantees

Kafka as Message Bus

Kafka as Message BusExcalidraw diagram · editable shapes · reveal step by stepExplore

Media Handling

Media HandlingExcalidraw diagram · editable shapes · reveal step by stepExplore

Multi-Device Sync

Multi-Device SyncExcalidraw diagram · editable shapes · reveal step by stepExplore

Chat Search

Chat SearchExcalidraw diagram · editable shapes · reveal step by stepExplore
10

Edge cases

Handling Edge Cases

Message Delivery Reliability

Message Delivery ReliabilityExcalidraw diagram · editable shapes · reveal step by stepExplore

WebSocket Connection Failure

WebSocket Connection FailureExcalidraw diagram · editable shapes · reveal step by stepExplore
11

Tradeoffs

Tradeoffs & Design Decisions Summary

Decision Option A Option B Chosen Why
Protocol HTTP Long Polling WebSocket WebSocket Bidirectional, low overhead, real-time push
Message DB MySQL (sharded) Cassandra Cassandra Write-heavy (20B/day), partition by conversation, linear scaling
Message Queue Redis Pub/Sub Kafka Kafka Durability, replay, consumer groups, ordering per partition
Presence Store Database Redis (TTL) Redis In-memory speed, TTL auto-expiration, pub/sub for updates
Message IDs UUID v4 Snowflake ID Snowflake Time-sortable, compact 64-bit, no coordination
Delivery Push only Push + offline queue Push + queue Guaranteed delivery even for offline users
Encryption TLS only (server-side) E2E (Signal Protocol) E2E Privacy — server never sees plaintext
Group encryption N×encrypt per message Sender Key Sender Key O(1) encryption per message instead of O(N)
Presence fan-out Push to all contacts Hybrid (push active + pull on demand) Hybrid Bounded fan-out, scales to 500M users
Multi-device Phone-primary Server-primary with per-device keys Server-primary All devices work independently
Media upload Through API server Direct to S3 (presigned URL) Direct S3 Offloads bandwidth from API servers
Search Server-side Elasticsearch On-device search Depends on E2E E2E → device only; no E2E → Elasticsearch
Redirect 301 vs 302 for links N/A N/A N/A
12

Reliability & fault tolerance

Workshop note · added for the website’s common reading format

Track accepted, delivered, and read states separately. Expect duplicate delivery and deduplicate by ID.

Set service-level objectives for the user-visible path, then map its dependencies. Define bounded retries with jitter, deadlines, and backpressure. Keep a degraded mode that protects authoritative state, and test recovery instead of treating replication as a backup.

For Chat System, pay special attention to Message queue, Message store, Presence store when deciding failure domains and recovery procedures.

13

Production architecture

Production Architecture

Production ArchitectureExcalidraw diagram · editable shapes · reveal step by stepExplore
14

Further exploration

Workshop note · added for the website’s common reading format

Rebuild Chat System from memory, then change one assumption: ten times more traffic, a new region, or a stricter consistency requirement. Which component must change first—and which does not?

Compare Message service with the same boundary in a related design. Write down one alternative you rejected, what it would simplify, and when you would choose it instead. Follow the source link at the end of this article to explore the original document.

15

Interview playbook

Interview Tips

  1. Start with protocol choice — "For real-time messaging, WebSocket is the clear winner over polling." Briefly explain why, then move on.

  2. Draw the 1:1 message flow first — It's the simplest. Show: sender → WS gateway → message service → persist + Kafka → delivery worker → recipient's WS gateway → recipient.

  3. Address "what if the recipient is offline?" early — This is the follow-up every interviewer asks. Show the offline queue + push notification path.

  4. Presence is a trap topic — Don't spend too long on it. Mention the fan-out problem, say "hybrid pull + push" and move on unless asked to deep-dive.

  5. Group messaging is just fan-out — "A group message is a 1:1 message sent to each member. The interesting part is how to fan out efficiently" → Kafka with conversation-level partitioning.

  6. E2E encryption shows depth — Mention Signal Protocol, X3DH, Double Ratchet. You don't need to derive the math — just show you understand why keys rotate per message (forward secrecy).

  7. Message ordering matters — Explain Snowflake IDs and why Kafka partitioning by conversation_id guarantees FIFO within a conversation.

  8. Multi-device sync is a common follow-up — "Sync cursor per device. On reconnect, replay from cursor."

  9. Don't forget media — "Media goes directly to S3 via presigned URL. Message contains only a pointer. CDN for delivery." This 3-sentence answer covers it.

  10. Scale numbers impress — "500M DAU × 40 messages = 20B messages/day = 231K messages/second. We need ~3,000 WebSocket servers at 50K connections each."