Skip to main content

Back-of-the-Envelope Estimation and the System Design Interview Framework

· 6 min read
Sivabharathy

There's a moment in every system design discussion where someone has to answer "okay, but will it actually handle that?" — and the people who freeze are the ones who never learned to estimate. Back-of-the-envelope math has a reputation for being scary, but it's genuinely just multiplication with round numbers. This post covers how I do quick capacity estimates, plus the four-step framework I use to keep a design conversation from turning into a rambling mess.

This is part two of my system design fundamentals series. Part one covered scaling, latency, and availability, which you'll want in your head for the estimation part.

Why estimate at all?

The point of a rough estimate isn't precision — it's catching bad ideas early. If a quick calculation says a design needs 500 servers, you know to rethink it before you've drawn twenty boxes. Estimates tell you whether data fits in memory or needs disk, whether one database is fine or you need sharding, whether bandwidth is a rounding error or the main constraint. You're aiming for the right order of magnitude, not the exact answer. Off by 2x is fine. Off by 100x means you missed something structural.

The building blocks

A few numbers make the math easy. Powers of two give you data sizes: a thousand is roughly 2 to the 10th (a kilobyte), a million is 2 to the 20th (a megabyte), a billion is 2 to the 30th (a gigabyte), a trillion is 2 to the 40th (a terabyte). Knowing that a "billion of something a byte each" is about a gigabyte makes storage estimates instant.

For time, round aggressively. There are 86,400 seconds in a day, but I just use 100,000 (10 to the 5th). That one substitution turns most "per day to per second" conversions into shifting a decimal point, and the error is small enough to ignore for a sanity check.

The other habit: state your assumptions out loud. "Assume 100 million daily active users, each posting twice a day" — now anyone can follow (and correct) your math. Hidden assumptions are where estimates go wrong.

A worked example: sizing a Twitter-like feed

Let's estimate the write load for a simplified Twitter. Say 100 million daily active users, and each posts twice per day on average. That's 200 million posts per day.

Convert to per second: 200 million divided by 100,000 seconds gives 2,000 writes per second on average. But traffic isn't flat — people post more at peak hours. A common trick is to assume peak is a few times the average, so call it roughly 6,000 writes per second at peak. Already this tells you a single naive database write path won't cut it; you'll need buffering or partitioning.

Now storage. If each post is about 300 bytes of text plus metadata, 200 million posts a day is roughly 60 GB per day. Over five years that's on the order of 100 TB. That number instantly rules out "keep it all on one box" and points you toward partitioning and tiered storage.

Reads are where it gets spicy. People read far more than they write — a read-to-write ratio of 100:1 isn't unusual for social feeds. So if writes peak around 6,000 per second, reads could be in the hundreds of thousands per second. That's the number that dictates your whole architecture: it's why feeds get heavily cached and often precomputed rather than assembled on every request.

Notice what just happened. Three lines of arithmetic told us we need write buffering, data partitioning, and aggressive read caching — before drawing a single component. That's the entire value of estimation.

The four-step framework

Estimation tells you the scale; you still need a way to structure the actual design. Whether it's an interview or a real design doc, I use the same four steps, and roughly the same time split.

Step 1: Understand the problem and pin down requirements

Resist the urge to start drawing. First, figure out what you're actually building. Separate functional requirements (what it does — post, follow, search) from non-functional requirements (how well — how many users, read/write ratio, latency target, consistency needs). Ask clarifying questions relentlessly. "Should the feed be real-time or is a few seconds of delay fine?" changes everything. Half of good design is refusing to solve the wrong problem.

Step 2: Propose a high-level design

Now draw the big boxes: clients, load balancer, application servers, databases, caches, maybe a queue. Keep it coarse. The goal is an end-to-end sketch that a reasonable person agrees could work, with the data flowing from request to response. Don't dive into any one box yet — you're establishing the skeleton so everyone shares a mental model.

This is also where your estimates earn their keep. If you calculated hundreds of thousands of reads per second, your high-level design had better show a cache, or someone's going to ask why not.

Step 3: Deep-dive into the critical components

Pick the parts that actually matter — usually the bottlenecks your estimates surfaced — and go deep. How is data partitioned? What's the caching strategy? How does the feed get generated? This is where you show you understand trade-offs: "we could precompute feeds on write for fast reads, but that's expensive for users with millions of followers, so we'd use a hybrid." You can't deep-dive everything, so spend your time where the scale pressure is.

Step 4: Wrap up — bottlenecks, trade-offs, and what you'd do next

Step back and stress-test your own design. Where does it break first? What's the single point of failure? What did you trade away, and would you make the same call at 10x the scale? Naming your design's weaknesses before anyone else does is the strongest signal that you actually understand it. No design is perfect; the mature move is knowing how yours is imperfect and what you'd fix next.

The habit underneath all of it

Both estimation and the framework are really the same skill: making the implicit explicit. State your assumptions, do the rough math, name your trade-offs. Once you're comfortable turning a vague "build Twitter" into "6,000 peak writes per second, 100 TB over five years, read-heavy, so buffer writes and cache reads," the design almost suggests itself.

Next in the series, I'll follow a request into the system — networking and load balancing — and unpack how traffic actually gets spread across all those servers we keep saying we'll add.