Chapter
Estimate Before You Architect
Convert workload assumptions into rough traffic, storage, bandwidth, and key-space requirements.
Learning objectives
- Convert daily request volume into average and peak requests per second
- Estimate retained storage and network throughput with explicit units
- Use orders of magnitude without pretending rough inputs are exact
- Connect each estimate to an architectural decision
Estimates tell you which problems are real
Before reading, retrieve two facts from your brief: which operation is most frequent, and which failure must the service tolerate? Keep them visible as you calculate.
The requirement brief assumes one million new links and one hundred million redirects per day. Are those numbers large enough to require partitioning? Would all link records fit on one machine? Is network bandwidth or storage likely to dominate?
Without estimates, every technology sounds potentially necessary. Back-of-the-envelope calculation gives the design proportions.
The goal is not a perfectly accurate forecast. The goal is to distinguish:
10 requests/second from 100,000 requests/second
10 gigabytes from 10 petabytes
one machine from a globally distributed fleet Keep a small unit vocabulary
Use approximations that are easy to calculate and explain:
1 day ≈ 100,000 seconds (actual value: 86,400)
1 KB ≈ 1,000 bytes
1 MB ≈ 1,000 KB
1 GB ≈ 1,000 MB
1 TB ≈ 1,000 GB Powers of two matter for some implementation details, but decimal approximations are usually clearer for capacity reasoning. State which convention you use and remain consistent.
Always carry units through the equation. A bare result such as 12,000 is ambiguous;
12,000 redirects/second can guide a decision.
Convert daily traffic to requests per second
The approximate formula is:
average requests/second = requests/day ÷ seconds/day For 100 million redirects per day:
100,000,000 redirects/day ÷ 86,400 seconds/day
≈ 1,157 redirects/second on average Traffic is rarely uniform. If we assume a peak of ten times the average:
peak redirects ≈ 11,570/second
round to roughly 12,000/second For one million creations per day:
1,000,000 ÷ 86,400 ≈ 12 creations/second average
10× peak ≈ 120 creations/second The system is read-heavy: redirects outnumber creations about 100 to 1. That fact makes the read path, not the write path, the first candidate for caching and horizontal scaling.
Average is not capacity
Predict before calculating
If creations double but redirects stay unchanged, do read QPS and five-year mapping storage both double? Explain your answer before continuing.
Check the distinction
Read QPS stays the same under these assumptions. Mapping storage doubles if record size and retention stay fixed. Read traffic and stored data are separate quantities; more data does not automatically mean proportionally more reads.
An average hides bursts. Morning traffic, a popular shared link, or a regional event may produce far more than the daily average. The peak multiplier is an assumption that should eventually be replaced by measurement, but ignoring peaks entirely creates a predictably fragile design.
Estimate retained storage
Assume one stored mapping occupies roughly 500 bytes after accounting for:
- the short code;
- the destination URL;
- timestamps and expiration;
- database record and index overhead.
At one million new mappings per day:
500 bytes/mapping × 1,000,000 mappings/day
= 500,000,000 bytes/day
≈ 500 MB/day For five years:
500 MB/day × 365 days/year × 5 years
≈ 912,500 MB
≈ 0.9 TB Round that to approximately 1 TB of primary data. Three durable copies would bring raw storage near 3 TB before backups, logs, and operational headroom.
This is substantial but not automatically a reason to build a complex sharded database on day one. The estimate tells us to preserve a path to partitioning while beginning with the simplest storage that meets current load and reliability needs.
Estimate network throughput
Suppose the redirect response, including headers, averages 1 KB. At a peak of 12,000 redirects per second:
12,000 responses/second × 1 KB/response
= 12,000 KB/second
≈ 12 MB/second
≈ 96 megabits/second The conversion to bits multiplies bytes by eight. Real traffic also includes requests, encryption overhead, retries, health checks, and internal service traffic. The estimate provides an order of magnitude, not a network invoice.
If the service returned large images instead of small redirects, bandwidth and CDN strategy would dominate much earlier. Workload shape matters more than fashionable architecture.
Make sure the identifier space is large enough
A short code using lowercase letters, uppercase letters, and digits has 62 possible symbols at each position. A seven-character code provides:
62⁷ = 3,521,614,606,208 possible codes That is about 3.5 trillion combinations—far more than the approximately 1.8 billion links created over five years at one million per day.
This does not make random generation collision-free. With uniform independent generation, the chance that the next candidate is already taken is the occupied fraction of the space. At 1.8 billion occupied codes, that is roughly 0.05% per candidate. This chance increases, not decreases, as the space fills. Across billions of attempts, collisions are expected even though any individual attempt is unlikely to collide. The creation path must still detect a duplicate code and retry; a large namespace is not a uniqueness guarantee.
Estimate memory for a cache
The storage estimate covered all retained links. Now consider a different question: what if one popular link is opened thousands of times? The straightforward redirect path asks the database for the same destination on every visit.
A cache keeps a reusable copy of a result, often in memory. The service can check that copy first and consult the database when it is missing. This can reduce repeated database work; the database still holds the durable mapping. Our task here is only to estimate how many such copies fit in a memory budget, not yet to design the cache.
Caching every retained record would eventually require approximately the same raw data size as the database, which is unnecessary. Popularity is usually uneven: a small portion of links may receive a large portion of redirects.
Suppose we provision 20 GB for cached mappings and estimate 500 bytes per entry:
20,000,000,000 bytes ÷ 500 bytes/entry
≈ 40,000,000 cached mappings That calculation does not promise a particular hit rate. It tells us how many entries fit. Observed traffic would determine whether those entries cover enough reads to justify the cache. The hit rate is the fraction of lookups answered by the cache. When memory fills, an eviction policy decides which entries to remove—for example, entries that have not been used recently. Capacity alone tells us neither which links visitors will request nor how often the cache will contain them.
Connect Capacity Estimates to Design Decisions
| Estimate | Possible design consequence |
|---|---|
| Reads outnumber writes 100:1 | Optimize and cache the redirect path first |
| Peak redirects are about 12,000/s | Benchmark safe per-instance capacity; size the fleet with headroom |
| Five-year primary data is about 1 TB | Plan backups and a partitioning path; avoid premature complexity |
| Responses are small | Redirect bandwidth is manageable; latency and request rate matter more |
| Seven base-62 characters provide trillions of codes | The namespace is adequate, but collisions still need handling |
An estimate that changes no decision may be unnecessary. Conversely, a decision justified only by “large scale” probably needs a number.
Precision should match the inputs
Writing 11,574.074 redirects/second suggests false accuracy when the traffic and peak
factor are assumptions. Prefer:
about 1.2K redirects/second average
about 12K redirects/second at an assumed 10× peak Keep a visible assumptions table so another person can change one input and recompute the consequences.
Practice: estimate a notification service
Assume:
50 million notifications/day
5× peak over average
2 KB per queued notification
500 bytes per stored delivery-history record, including index overhead
retain delivery records for 30 days
each worker sends 100 notifications/second Estimate:
- average and peak notifications per second;
- temporary storage if one full day accumulates in the queue;
- retained delivery-history storage before replication;
- the minimum worker count at peak, then add reasonable headroom;
- which assumption you would most want to validate in production.
Write units beside every intermediate result and finish each estimate with the architectural question it helps answer.
A scaffold if you get stuck
Divide daily notifications by 86,400; multiply that result by five for peak rate. For history, multiply notifications/day × days × bytes/record. Do not use queue payload size for a different kind of record. Divide peak rate by worker throughput and round up.
Worked estimates and their consequences
Average: 50,000,000 / 86,400 ≈ 579 notifications/s
Peak: 579 × 5 ≈ 2,900 notifications/s
One-day backlog: 50,000,000 × 2 KB ≈ 100 GB
History: 50,000,000 × 30 × 500 bytes ≈ 750 GB
Workers: ceiling(2,900 / 100) = 29 at peak For a provisional 30% capacity margin, round 29 × 1.3 up to 38 workers. Explain that the margin is a choice to validate, not a guarantee. Check provider rate limits and measured worker throughput before relying on it. A one-day backlog is an outage scenario, not normal queue size. With 38 workers and peak arrivals of 2,900/s, spare capacity is only 900/s: draining 50 million waiting jobs takes about 15.4 hours if those rates persist. Provisioning enough to keep up is different from provisioning enough to recover quickly.
Transfer and delayed review
Without reusing the answers, estimate a service receiving 2 million reading-list saves/day, with a 4× peak and 1 KB per saved item retained for one year. Which extra input is necessary to estimate its read fleet?
Check the transfer exercise
About 23 writes/s average, 93/s peak, and 730 GB primary storage. You still need the read workload and safe per-instance capacity; write volume alone cannot size the read fleet.
Next session, redo one estimate without the formulas. Later in the week, change retention and peak traffic separately and explain which quantities each change affects.
Chapter checkpoint
You should now be able to move from a workload statement to approximate QPS, storage, bandwidth, and namespace size. More importantly, you should be able to say why each number matters to the design.