Interview Walkthrough: Sizing a Messaging Service Live
The previous lessons worked a media-heavy service where bandwidth and storage dominated. This walkthrough runs the same method on a service with the opposite profile — enormous message volume, tiny payloads — and lands on a completely different constraint.
Key takeaway
The purpose of a BOTEC is not to produce numbers. It is to find which resource binds first, because that resource dictates the architecture. Run all four estimates — compute, connections, storage, bandwidth — and the largest one is your design.
Step 0 — Scope before you compute
"Design a messaging service like WhatsApp."
Ask first:
- How many users, and how many are active daily?
- Messages per user per day?
- One-to-one, or group chats? Group size changes fan-out completely.
- Media, or text only? (This is the question that decides whether storage matters.)
- Are messages retained forever or deleted after delivery?
- Do we need delivery receipts and online presence? Both are extra traffic.
Then commit:
"I'll assume 1 billion registered users, 500 million DAU, 40 messages per user per day, mostly one-to-one, average message 200 bytes including metadata. I'll assume messages are retained. Let me size it and see what binds first."
Step 1 — Volume
Messages/day = 500M * 40 = 20 billion Messages/sec = 20 billion / 86,400 = ~231K/sec (average) Peak (Pareto) = 0.8 * 20B / 17,280 = ~926K/sec
Using the 80/20 rule from Lesson 7 — 80% of traffic inside a 4.8-hour window — peak is roughly 926,000 messages per second.
Step 2 — Compute
Against the 64,000 RPS reference server from Lesson 5:
Servers (CPU) = 926K / 64,000 = ~15 servers
Fifteen servers. Note the plausibility check immediately: that is small for a billion-user service, which suggests compute is not the constraint here — consistent with messaging being cheap per operation. Keep it and move on.
Step 3 — Concurrent connections
This is the estimate people forget, and for messaging it is decisive. Messaging clients hold persistent connections so the server can push messages without polling.
Assume 20% of DAU are connected simultaneously Concurrent connections = 500M * 20% = 100 million
How many can one server hold? Lesson 7 gave a real data point: WhatsApp managed 2 million concurrent TCP connections per server in 2012.
Servers (connections) = 100M / 2M = ~50 servers
Step 4 — Storage
Text/day = 20B * 200 B = 4 TB/day Text/year = 4 TB * 365 = 1.46 PB/year With 3x replication = ~4.4 PB/year
Now compare against the Twitter estimate from Lesson 9:
| Service | Items/day | Storage/day | Storage/year | Why the difference |
|---|---|---|---|---|
| Twitter-like | 1.5 billion | 255 TB | 93 PB | Video is 88% of the bytes |
| Messaging (text) | 20 billion | 4 TB | 1.46 PB | No media — payloads are 200 bytes |
13x more items, 64x less storage. That contrast is the single most useful thing to say here: item count tells you nothing about storage until you know the payload size.
Step 5 — Bandwidth
Outgoing = 231K/sec * 200 B * 8 = ~370 Mbps
Against Twitter's 393 Gbps of egress, this is roughly 1,000x smaller — comfortably inside a single instance's 25 Gbps NIC.
Step 6 — Which resource binds?
State the conclusion explicitly:
"Connections bind first. Bandwidth is trivial, compute is modest, storage is manageable. So this is a connection-management problem: I'd use event-driven servers optimized for many idle sockets, keep per-connection memory small, and put a connection-aware routing layer in front so a user's messages reach the server holding their socket. Adding CPU would buy me nothing."
That paragraph is the entire payoff of the exercise, and it is what the interviewer is actually listening for.
Deep dives
"What if we add group chats with 100 members?"
Fan-out multiplies delivery, not sending. A message sent once is delivered 100 times, so outgoing message rate goes from 926K/sec to potentially 92M/sec at peak. Bandwidth is still small in absolute terms — 92M times 200 bytes times 8 is about 148 Gbps, which is real but manageable. The bigger problem is that each delivery must find the recipient's connection, so the connection-routing layer takes 100x the lookups. I'd fan out asynchronously through a queue rather than synchronously on the sender's request, so the sender's latency doesn't scale with group size.
"What if we add media?"
It inverts the whole estimate, exactly like Twitter. If 5% of messages carry a 500 KB image, that's 1 billion media messages a day at 500 TB/day — over 100x the text storage, and it makes bandwidth the new constraint. I'd immediately separate the paths: media goes to object storage with a CDN and the message carries only a reference. That keeps the messaging path small and fast, and it's why real messaging systems never put bytes in the message.
"Your 20% concurrent assumption — where did it come from?"
It's a judgment call and it's load-bearing, so it's worth flagging. If it's actually 40%, connections double to 200 million and I need 100 servers instead of 50. The conclusion doesn't change — connections still bind — which is why I'm comfortable proceeding. That's the test I'd apply to any assumption: does a 2x error change the decision? Here it doesn't, so I don't need to be more precise.
"How would you validate any of this in production?"
These are BOTECs, so they establish feasibility and identify the constraint, nothing more. In production I'd measure real connection counts, message-size distribution, and the concurrency ratio, then use synthetic workloads to validate per-server connection limits before committing to a fleet size. The estimate tells me what to instrument first — here, connections per server — which is a genuinely useful output even when the numbers turn out wrong.
Now do it live
The next section drills these calculations individually, with model answers.