Strong system design starts with the problem definition, not the database choice.
Requirements and capacity estimates give the architecture a reason to exist in its chosen form.
Beginners often skip this step because it feels less exciting than diagrams, but it is one of the highest-value habits in design work.
Professionals use it to avoid overbuilding, underbuilding, and arguing about architecture without shared assumptions.
If you do not know who the users are, which actions are most important, what latency matters, and which failure scenarios are acceptable, then architecture choices become mostly decorative. You may draw a system, but you cannot defend it convincingly.
Requirement work is therefore not slow bureaucracy. It is the foundation that gives your design meaning.
Capacity estimation does not need to be perfect math to be useful. Rough order-of-magnitude thinking already helps separate tiny systems from large ones and changes which bottlenecks deserve attention.
Professionals estimate reads, writes, storage growth, bandwidth, and concurrency not because they expect exact numbers, but because scale assumptions shape sensible design choices.
Suppose the prompt is "design a photo-sharing feed." A beginner may immediately draw mobile clients, services, databases, and caches. A stronger start is to list the user actions: upload a photo, follow an account, publish a post, open a feed, and delete content. This establishes what the system must actually do before discussing components.
Next separate functional requirements from quality requirements. Functional requirements describe behavior. Quality requirements describe acceptable latency, availability, durability, security, consistency, geography, and cost. Ask which actions are essential for the first version and which can wait. A smaller explicit scope produces a more defensible design than an impressive diagram for an undefined product.
Finally attach rough numbers to the important paths. Estimate daily active users, actions per user, read-to-write ratio, peak multiplier, average object size, retention period, and expected annual growth. These values do not need to be perfect. They need to expose which assumptions drive storage, bandwidth, database load, caching, and partitioning decisions.
In interviews, strong clarification makes you look grounded. In real projects, it prevents the team from optimizing for the wrong thing. In both settings, it gives later architecture discussion a much firmer base.
Good estimates also create productive follow-up questions: do we care more about read throughput, write durability, latency, or cost? Those are the questions that actually move a design forward.
Calculate peak reads and writes, image bytes, metadata growth, bandwidth, cache hit assumptions, and replication overhead for a five-year horizon.
Work through this as a controlled engineering exercise rather than a copy-and-paste demo. State the expected result before running anything, keep the input small enough to inspect, and record the important intermediate state. That makes the lesson explain not only what to type, but why the result is trustworthy.
Using daily averages hides peaks, and quoting precise numbers from guesses creates false confidence. Missing retention and growth factors can change the storage design by orders of magnitude.
Verification must use evidence that matches the concept. Show formulas, ranges, and sensitivity to the two weakest assumptions; connect each estimate to a later partitioning, cache, or delivery decision. Repeat the check after deliberately introducing the failure, then after the fix. The contrast between those runs is the part that turns a definition into practical understanding.
Experienced designers do not present one estimate as truth. They calculate a reasonable range and test sensitivity. If average photo size doubles, does storage cost merely increase or does the upload architecture also change? If the peak factor rises from three to ten during an event, which component saturates first? Sensitivity analysis identifies the assumptions worth validating with product or analytics teams.
Translate reliability language into budgets. A 99.9 percent monthly availability target permits roughly forty-three minutes of downtime, while 99.99 percent permits only a few minutes. Those targets influence regional redundancy, failover automation, operational staffing, and cost. Apply strict targets only to journeys whose business impact justifies them.
Capacity work should end in decisions, not a spreadsheet. State why a CDN is needed, when a cache becomes worthwhile, how many partitions are initially required, and what metric triggers the next scaling step. Include headroom and degradation plans so the system can shed optional work before critical operations fail.
This is better than immediately naming databases or queues.
Who are the users, what are the core actions, how often do they happen, what latency matters, how much growth do we expect, and what failures are unacceptable?
Adapt this focused example to a disposable local environment and inspect every result before expanding it.
DAU = 10,000,000
Feed opens/user/day = 8
Peak factor = 5
Peak feed RPS = DAU * opens / 86400 * peak factor
Storage/year = uploads/day * average bytes * 365 * replication
Use explicit units so another engineer can review every assumption.
Daily active users: 10,000,000
Feed opens per user per day: 8
Average feed requests/second: 10,000,000 * 8 / 86,400 = 926
Peak multiplier: 5
Peak feed requests/second: 4,630
Uploads per user per day: 0.2
Average compressed photo: 2 MB
New photo storage per day: 4 TB before replication
Tie each number to a specific design consequence.
High read/write ratio -> cache feed pages and use a CDN for media
4 TB new media/day -> object storage with lifecycle policies
Event peak uncertainty -> autoscaling plus admission control
Strict upload durability -> direct-to-object-storage upload
Loose feed freshness -> asynchronous fan-out is acceptable
No. Reasonable approximations are often enough to guide architecture in the right direction.
Because they reveal whether your architecture is grounded in the actual problem or built from generic habits.
Explore 500+ free tutorials across 20+ languages and frameworks.