Chapter

Estimate Before You Architect

Convert workload assumptions into rough traffic, storage, bandwidth, and key-space requirements.

65 min 4 objectives
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

My notes & review

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:

Code
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:

Code
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:

Code
average requests/second = requests/day ÷ seconds/day

For 100 million redirects per day:

Code
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:

Code
peak redirects ≈ 11,570/second
round to roughly 12,000/second

For one million creations per day:

Code
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

Checkpoint

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:

Code
500 bytes/mapping × 1,000,000 mappings/day
= 500,000,000 bytes/day
≈ 500 MB/day

For five years:

Code
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:

Code
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:

Code
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:

Code
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

EstimatePossible design consequence
Reads outnumber writes 100:1Optimize and cache the redirect path first
Peak redirects are about 12,000/sBenchmark safe per-instance capacity; size the fleet with headroom
Five-year primary data is about 1 TBPlan backups and a partitioning path; avoid premature complexity
Responses are smallRedirect bandwidth is manageable; latency and request rate matter more
Seven base-62 characters provide trillions of codesThe 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:

Code
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:

Code
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:

  1. average and peak notifications per second;
  2. temporary storage if one full day accumulates in the queue;
  3. retained delivery-history storage before replication;
  4. the minimum worker count at peak, then add reasonable headroom;
  5. 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
Code
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.