---
title: "Back-of-the-envelope calculation for system design"
description: "Estimate requests per second, peak load, bandwidth and storage from product assumptions, then check the guess against a measured PostgreSQL table."
canonical_url: "https://fanout.sh/system/archive/back-of-the-envelope-capacity-planning"
md_url: "https://fanout.sh/system/archive/back-of-the-envelope-capacity-planning.md"
access: "public"
---

# Back-of-the-envelope calculation for system design

Estimate requests per second, peak load, bandwidth and storage from product assumptions, then check the guess against a measured PostgreSQL table.

## Public overview

Back-of-the-envelope capacity planning

Capacity planning turns product assumptions into approximate request rates, storage, bandwidth, and operating cost. The estimate should expose likely bottlenecks and help choose what to measure next. Extra decimal places do not make uncertain inputs more reliable.

We will estimate a feed's read traffic, account for work hidden behind each request, and compare the shortener's storage allowance with a historical measurement.

Turn user activity into a rate

Start with active users and actions per user, not the total number of registered accounts. Suppose a feed has 10 million daily active users, each making 20 feed requests per day.

Step Calculation Result --- --- --- Daily reads 10 million × 20 200 million requests Average rate 200 million ÷ 86,400 seconds About 2,300 requests per second Assumed busy period Average × 10 About 23,000 requests per second

The tenfold peak is an assumption to replace with traffic evidence. If plausible peaks range from 20,000 to 50,000 requests per second, compare designs across that range. A design that works only at the rounded midpoint has little margin for uncertainty.

Record where the traffic arrives, how long bursts last, and whether one tenant or popular item concentrates the load. A global daily total does not describe the busiest region or partition. Revisit the estimate for growth, launches, and seasonal demand.

Count the work behind one request

A feed request might return 20 items. Fetching each item with a separate database query would produce roughly 460,000 lookups per second at the assumed peak, before retries or cache misses. That estimate is a reason to inspect batching and query shape; it does not by itself prove that any particular database cannot cope.

Separate reads, writes, background jobs, and fanout. One new post can cause many feed updates. One redirect in our shortener also writes an event, so a product with many more reads than creations is not necessarily read-heavy at the database.

Bandwidth needs bytes as well as requests. At an illustrative 20 kB response payload, 23,000 feed responses per second carry about 460 MB/s, or 3.7 Gbit/s, before protocol overhead. These decimal units describe payload leaving that serving boundary; compression, caches, and network placement change what each link carries.

Keep the latency target beside the rate. “Handles 23,000 requests per second” is not sufficient if the queue grows throughout the test and users wait longer each minute.

Build storage from retention and representation

For a steady write rate, start with:

Retained records = records per day × retention days.

---
This representation contains public Fanout content only. Protected Pro lessons, account data, billing, checkout, and pricing are not included.

Browse the public content map: https://fanout.sh/sitemap.md
