Step 1: Requirements and estimates
Before drawing anything, agree on what you’re building. A chat app can mean many things, and each feature changes the design. Ask, then write down a short list:
Functional:
- One-to-one chats and groups (up to, say, 500 members).
- Text messages and images.
- Messages are delivered even if the recipient is offline, with a push notification.
- Sent, delivered and read indicators.
- Online / last seen status.
- History available on several devices (phone and tablet).
Non-functional:
- Low latency: a message should arrive in well under a second when both users are online.
- No lost messages, and no duplicates shown.
- Messages in a conversation appear in the same order for everyone.
Out of scope (say it out loud): voice and video calls, end-to-end encryption details, message search, channels with millions of members.
Clarify the parameters that change the architecture: group size (fan-out cost), multi-device (per-device delivery state, sync), retention (storage and cost), end-to-end encryption (server can’t read, index or moderate; per-device keys and fan-out of ciphertext), ordering scope (per conversation is enough; global is neither needed nor feasible), and delivery semantics (at-least-once with client deduplication, presented as exactly-once).
Daily active users: 100 million
Messages per user per day: 40
Messages per day: 4 billion
Average per second: 4e9 / 100,000 s ≈ 40,000 / s
Peak (×3, evening hours): ≈ 120,000 messages / s written
Delivered (avg 1.5 recipients, ≈ 200,000 deliveries / s at peak, plus receipts:
some groups): several hundred thousand small events / s
Message size (text + metadata): ~200 bytes → 4e9 × 200 B ≈ 0.8 TB / day ≈ 300 TB / year
Images: stored in object storage behind a CDN, not in the message store
Concurrent connections: ~30% of DAU online at peak ≈ 30 million open WebSockets
at ~100,000 per gateway server → ~300 gateway servers- Write-heavy: every message is a write, and most are read only a few times. This rules out designs that are only good at reads.
- Connection-heavy: tens of millions of phones keep a connection open at the same time, which needs its own layer of servers.
- Storage grows forever unless there’s a retention policy; images go to object storage and a CDN, never into the message database.
- Scope: 1:1 + groups (≤500), text + media, offline delivery with push, sent/delivered/read, presence, multi-device history. Out: calls, E2EE details, search, huge channels.
- ~40k msg/s average, ~120k peak; ~300 TB/year of text; ~30M concurrent sockets → hundreds of gateways.
- Per-conversation ordering; at-least-once delivery with client dedup; media in object storage + CDN.
Check this part
Where should images sent in chats be stored?
What ordering does a chat app need?