Skills101

System Design · Lesson 7 of 8 · Updated ·

System Design Case Study — Design a Chat App Like WhatsApp

Designing a chat app like WhatsApp tests real-time communication, huge write volume and delivery guarantees. Let's solve it step by step.

Chat design: Asha's phone sends a message to chat servers over WebSocket; servers save it to the message store, deliver it to Ravi's phone, check presence, and use a push service if Ravi is offline. 50 million daily users × 40 messages = 2 billion messages a day

Step 1 — Requirements

Functional: one-to-one chat, group chat (up to ~256 members), online/last-seen status, sent ✓ / delivered ✓✓ / read receipts, works when the receiver is offline (deliver later + push notification), media sharing.

Non-functional: very low latency (messages appear instantly), messages never lost, ordered within a chat, end-to-end encryption, works on weak mobile networks.

Step 2 — Estimates

Assume 50 million daily active users, each sending 40 messages a day:

QuantityCalculationResult
Messages / day50 M × 402 billion
Messages / second2 B ÷ 86,400≈ 23,000 (peak ≈ 70,000)
Text storage / day2 B × ~100 bytes≈ 200 GB
Per year200 GB × 365≈ 73 TB (media much more, stored separately)

This is write-heavy — very different from the URL shortener.

Step 3 — Real-time connection: WebSockets

Normal HTTP is request–response: the server can't push a new message to you. Options:

MethodHowVerdict
Pollingask "any new messages?" every few secondswasteful, slow
Long pollingserver holds the request open until there's newsbetter, still clunky
WebSocketone persistent two-way connection✅ what chat apps use

Each user keeps a WebSocket to a chat server. A connection registry (in Redis) records which server each online user is connected to.

Step 4 — Message flow (Asha → Ravi)

  1. Asha's app sends the message over her WebSocket to chat server A.
  2. Server A stores it (with a unique, time-ordered message id) and acks Asha → ✓ sent.
  3. Server A looks up Ravi's connection:
    • Online on server B → forward to B → B pushes it to Ravi → Ravi's app acks → ✓✓ delivered sent back to Asha.
    • Offline → keep it as undelivered and send a push notification (FCM/APNs). When Ravi reconnects, his app fetches pending messages.
  4. When Ravi opens the chat → read receipt flows back the same way.

Retries + idempotent message ids (the client generates an id) mean a resent message is never shown twice.

Step 5 — Storage

  • Access pattern: "give me the latest 50 messages of conversation X", then scroll older. Huge write volume.
  • A wide-column store like Cassandra (partition key = conversation_id, clustering by message time) fits well; WhatsApp-style systems also delete messages from servers once delivered.
  • Media (photos, videos) go to object storage (S3-like) + CDN; the message just carries a link.
  • User profiles, groups, contacts → a regular SQL database.

Step 6 — Groups and presence

  • Group message: store once per group; the server fans out delivery to each member's connection/push. For very large groups, fan-out work goes through a queue.
  • Presence (online / last seen): clients send heartbeats every ~30 seconds; presence lives in Redis with a short TTL. Only send presence updates to people who have that chat open (otherwise it's a flood).

Trade-offs and extras to mention

  • Ordering: guarantee order within a conversation using per-conversation sequence numbers; global order isn't needed.
  • End-to-end encryption (Signal protocol): servers store only encrypted blobs.
  • Multi-device sync and message search add complexity — mention as follow-ups.

Quick recap

  • ~2 B messages/day, ~23K/s average: write-heavy.
  • WebSockets for real-time; a registry maps users to chat servers.
  • Store → ack (✓) → deliver or push → ack (✓✓) → read receipt.
  • Cassandra-like storage by conversation; media in object storage + CDN; Redis for presence.

Practice what you learned

📝 Quiz: Design a Chat App5 questions · instant answers & explanations · +10 XP · counts towards your free certificateTake the quiz →