Chapter
System Design Is a Conversation
Turn an ambiguous product idea into explicit behavior, priorities, scope, and constraints before drawing infrastructure.
Learning objectives
- Separate functional requirements from quality requirements
- Identify actors, core workflows, and deliberately excluded scope
- Convert vague qualities into measurable targets
- Produce a short design brief that later decisions can defend
A diagram is not the beginning
Suppose someone says, “Design a URL shortener.” It is tempting to draw boxes labeled
load balancer, cache, and database. Those boxes may eventually belong in the design,
but nothing in the request tells us which ones are necessary.
We do not yet know whether links expire, whether users can choose aliases, whether redirects must be counted, or how much traffic the system receives. A design chosen before those facts is a collection of familiar technologies rather than a response to a problem.
System design is the process of turning needs and constraints into a set of components that work together. The first task is therefore to understand the needs and constraints.
Functional requirements describe behavior
A functional requirement states something the system must allow an actor to do. An actor may be a person, another service, or an automated process.
For a small URL-shortening service, the essential workflows might be:
- A user submits a long URL and receives a short URL.
- A visitor opens the short URL and is redirected to the original destination.
Possible additions include custom aliases, expiration dates, accounts, link editing, analytics, and abuse reporting. Each addition changes the design. Editing means a short code can point somewhere new. Analytics may add a high-volume event pipeline. Accounts introduce ownership and authorization.
An MVP becomes easier to reason about when it says both what is included and what is not:
Included
- create a short link
- redirect from the short link
- optional expiration supplied at creation
Not included yet
- custom aliases
- editing an existing destination
- per-click analytics
- public discovery or search This is not avoiding complexity. It is deciding which complexity belongs to the current problem.
Quality requirements describe how well it must behave
Requirements such as “the service should be fast and reliable” sound useful but cannot guide a tradeoff. How fast? Reliable under what conditions? Which operation matters most?
A quality requirement, sometimes called a non-functional requirement, describes a property of the system rather than a user action. Common qualities include:
- latency: how long an operation takes;
- availability: how often the operation can be used successfully;
- durability: how unlikely accepted data is to be lost;
- throughput: how much work the system handles per unit of time;
- consistency: when different readers must observe the same state;
- security and privacy: who may act on or observe data;
- cost: what resources the system can reasonably consume.
Make the important qualities measurable. For this example, we might propose:
- Redirects should usually complete within 100 ms from the service edge.
- Redirects should remain available during the failure of one application instance.
- Once link creation succeeds, the mapping must survive an application restart.
- A newly created link may take up to a few seconds to appear in caches. These are provisional targets, not universal truths. Their purpose is to make later decisions testable. If the actual product owner needs immediate global visibility or a stricter availability target, the architecture may change.
Scale is part of the problem statement
The same behavior can require very different systems at different scales. A team utility handling 500 links is not the same engineering problem as a public service handling billions of redirects.
Ask for—or explicitly assume:
- creations per day;
- redirects per day and peak traffic;
- expected retention period;
- average record and response sizes;
- geographic distribution;
- read-to-write ratio;
- expected growth.
If exact values are unavailable, choose round numbers and label them as assumptions. The next chapter will turn them into approximate resource needs.
Priorities resolve conflicts
Systems cannot maximize every quality simultaneously. More replicas may improve resilience but increase cost. Stronger coordination may simplify consistency but add latency or reduce availability during network failures. Longer cache lifetimes reduce database traffic but delay updates.
For the URL shortener, an initial priority order could be:
- Correct and highly available redirects
- Durable link mappings
- Low redirect latency
- Reasonable operating cost
- Immediate analytics
The order tells us what to protect when two goals conflict. Analytics is not unimportant; it is simply allowed to lag behind the redirect path.
Write a brief before drawing
A useful design brief fits on one screen:
Product: public URL-shortening service
Core behavior
- Create an immutable short-code → destination mapping
- Redirect a visitor who supplies a valid short code
- Return a clear not-found or expired response otherwise
Scale assumptions
- 1 million new links per day
- 100 million redirects per day
- traffic may peak at 10× the daily average
- retain mappings for five years unless they expire
Important qualities
- redirects favor availability and low latency
- accepted mappings must be durable
- creation may be slower than redirect
Out of scope
- accounts, custom aliases, editing, analytics dashboards Every later box should trace back to something in this brief. A cache would address redirect latency and read volume. Replication would address availability and durability. If a component cannot be connected to a requirement or an observed bottleneck, it may not belong yet.
Failure questions reveal hidden requirements
Normal behavior is only half a design. Ask what should happen when:
- the requested short code does not exist;
- a destination is malformed or unsafe;
- two creations generate the same code;
- the application restarts after acknowledging a creation;
- the database is temporarily unavailable;
- one client creates thousands of links per second;
- an expired link remains in a cache.
You do not need to solve all of these immediately. Recording them prevents the happy-path diagram from pretending the questions do not exist.
Practice: create a requirement brief
Choose a simple notification service that can send email and mobile push notifications. Before naming any infrastructure, write:
- two essential user-visible behaviors;
- two deliberately excluded behaviors;
- three measurable quality requirements;
- three workload assumptions;
- two failure questions;
- a priority order for delivery, durability, latency, and cost.
There is no single correct brief. A good brief is internally consistent and specific enough that two engineers can discuss why a later design decision serves it.
Chapter checkpoint
Before moving on, you should be able to explain:
- the difference between behavior and quality;
- why “fast” and “scalable” are incomplete requirements;
- which parts of the URL-shortener example are intentionally out of scope;
- how a priority order helps when desirable qualities conflict.
The output of this chapter is not a diagram. It is a problem precise enough to estimate.