Skip to main content

Capacity Planning & Back-of-Envelope Sizing

Level 4: Level 4: Scaling Compute & Trafficmedium30 mincapacitysizinglittles-law

Size with Little's Law, divide by a 50-70% utilization target because queues explode near 100%, add N+1 AZ redundancy, and split capacity across reserved/on-demand/spot.

From "how much traffic" to "how many machines"

Capacity planning is turning traffic numbers into machine counts you can defend on a whiteboard. The core engine is Little's Law: in a stable system, the average number of requests in flight equals arrival rate times average time-in-system.

  L (concurrency) = lambda (RPS) x W (latency in seconds)

If you serve 50,000 RPS and each request spends 100ms (0.1s) being processed, average concurrency is 50000 x 0.1 = 5000 requests in flight simultaneously. That is the real sizing number: not RPS, but concurrent work. If one instance can hold ~250 concurrent requests before its own latency degrades, you need 5000 / 250 = 20 instances just to hold steady-state concurrency.

Never size to 100%

You never size to 100% of steady state, for two reasons rooted in queueing theory. First, utilization and latency are not linear. As utilization approaches 100%, queue length and wait time explode toward infinity (the 1/(1-rho) term): going from 70% to 90% utilization can double or triple your p99. Second, you need slack to absorb bursts and GC/pause jitter. So you target 50 to 70% utilization: 20 instances at a 70% target becomes 20 / 0.7 = ~29 instances.

Redundancy math

You must survive failure of a whole availability zone, so you spread instances across (typically) 3 AZs and size so that losing one AZ still leaves enough capacity. This is N+1 thinking at the AZ level. If 29 instances serve peak at target utilization across 3 AZs, losing one removes a third of the fleet; to keep the surviving two AZs at or below target after a zone loss, provision ~50% more, so 2/3 of the fleet still covers 100% of peak. So ~29 becomes ~44 instances (roughly 15 per AZ).

Check yourself
A fleet of 30 instances serves peak at a 65% utilization target, spread evenly across 3 AZs, with no extra AZ factor applied. One AZ fails at peak. What happens to the 20 survivors?

Finally, peak-to-average ratio sets autoscaling bounds and the reserved-vs-on-demand mix. Buy reserved/savings-plan capacity for the always-on baseline (cheapest per hour), on-demand for the predictable daily peak, and spot for burst or batch (cheapest but pre-emptible). You do not reserve for peak, because peak is a small fraction of the day.

Check yourself

You have sized the fleet. Now match each slice of capacity to the purchase model that fits it.

The always-on baseline that is still serving at 3am
The predictable daily peak above the baseline
Interruptible nightly batch jobs
The single busiest traffic hour of the year

Interview nuance: the fastest way to sound junior is to divide RPS by "requests per second per server" and stop. The fastest way to sound senior is to (1) convert to concurrency with Little's Law, (2) apply a utilization target and say why (queues explode near 100%), and (3) add explicit N+1 AZ redundancy. State the estimation chain out loud: DAU x actions/user/day / 86,400s x peak multiplier = peak RPS. Interviewers grade the method, not the exact number.

Recap: size with Little's Law (concurrency = RPS x latency), divide by a 50 to 70% utilization target because queues blow up near 100%, add N+1 AZ redundancy so losing a zone stays above peak, and split the resulting capacity across reserved/on-demand/spot by peak-to-average ratio.

Check yourself
Run the whole chain: 30,000 RPS at peak, each request spends 150ms in the system, one instance holds 300 concurrent requests before its tail degrades, 3 AZs. Which fleet size can you defend?

Apply

Your turn

The task this lesson builds to.

Size the fleet for a service that must serve 50k RPS at p99 < 200ms and survive one AZ failure.

Think about

  1. How does Little's Law convert RPS and latency into instance count?
  2. What utilization target leaves headroom for spikes and failover?
  3. How does N+1/N+2 AZ math change the count?

Practice

Make it stick

A second problem on the same idea, so it survives past today.

Size the read fleet for a service like Twitter's home-timeline API that must serve 300k RPS at p99 < 150ms across 3 regions, where each request fans out to a Redis timeline cache plus 2 downstream calls, and you must survive losing an entire region. Lead with your estimation chain.

Think about

  1. What must each region carry when a peer region dies?
  2. Why must the downstreams be sized for the failover surge too?
  3. Can the failover headroom be warm-but-light rather than fully provisioned?