# System Design Case Study — Design a Chat App Like WhatsApp

Source: https://skills101.in/learn/system-design/design-chat-app — Skills101 free tutorial (System Design). Updated 2026-11-09.

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](https://skills101.in/learn-img/system-design/chat-app.svg)

## 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**:

| Quantity | Calculation | Result |
|---|---|---|
| Messages / day | 50 M × 40 | **2 billion** |
| Messages / second | 2 B ÷ 86,400 | **≈ 23,000** (peak ≈ 70,000) |
| Text storage / day | 2 B × ~100 bytes | **≈ 200 GB** |
| Per year | 200 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:

| Method | How | Verdict |
|---|---|---|
| Polling | ask "any new messages?" every few seconds | wasteful, slow |
| Long polling | server holds the request open until there's news | better, still clunky |
| **WebSocket** | one 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 quiz and free certificate: https://skills101.in/learn/system-design/design-chat-app