Chapter

System Design Is a Conversation

Turn an ambiguous product idea into explicit behavior, priorities, scope, and constraints before drawing infrastructure.

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

My notes & review

Start With Requirements Before Drawing Architecture

Read this part with a notebook or an empty document beside you. You need basic programming knowledge, but no prior distributed-systems vocabulary. Each chapter builds one artifact: a brief, estimates, a contract, and finally an architecture. Keep them together and revise earlier assumptions when a later decision exposes a gap.

Try each checkpoint before opening its answer. The answer is a comparison, not a script to memorize. At the start of your next study session, reconstruct the previous artifact for five minutes without looking. Then check what you missed. The site’s completion button records reading progress; it does not certify that you can perform these design tasks.

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:

  1. A user submits a long URL and receives a short URL.
  2. 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:

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

Code
- Over each day, 99% of successful redirects should finish within 100 ms,
  measured from request arrival at our edge to response departure.
- Redirects should remain available during the failure of one application instance.
- Once link creation succeeds, the mapping must survive an application restart.
- Once creation succeeds, the next redirect must find the mapping, even if uncached.

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.

The latency target does not include the visitor’s network or the destination page loading. And fast successful requests do not prove availability: failed requests need a separate measure. “99% within 100 ms” means at least 99 out of 100 successful requests meet the threshold over the measurement window, not that their average is 100 ms. This distinction prevents many fast requests from hiding a small group of very slow ones. See Google SRE’s explanation of service objectives.

Suppose a user creates a short link and immediately opens it. The requirement is that the destination can be found—not that we use a particular storage technology.

Later we may add a cache, a temporary store of mappings that are quicker to retrieve, or a database replica, another copy of the stored data. An empty cache is acceptable if we can look up the mapping in the database. A copy that has not yet received the new mapping must not cause us to return “not found.” This is why we state the user-visible requirement before choosing the mechanism.

Checkpoint

Turn a vague promise into a test

“Users can create expiring links, and the service is fast.” Which part describes behavior? Rewrite the other part with an operation, threshold, fraction of requests, and measurement window. What time interval will you measure?

Compare your reasoning

Creating expiring links is behavior. One possible quality target is the redirect target above. A creation-latency target is also valid if you name creation explicitly. “Use a cache” is not a quality target: it selects a mechanism before stating what success means.

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

The requirements above can pull a design in different directions. Suppose we keep a second copy of link data so one machine failing does not erase our only copy. That extra copy costs storage and must receive updates: resilience creates additional work.

Now suppose link creation waits until both copies confirm an update. Readers can be given a stronger freshness guarantee, but creation takes longer and may have to wait when one copy cannot be reached. This agreement between machines is coordination. We will study the mechanisms later; the point here is to decide which user promises justify the extra waiting.

Similarly, keeping a frequently requested mapping in a cache avoids repeated database lookups. If destinations can change, keeping that cached copy too long can send a visitor to the old destination. Faster reads and fresher answers may require different choices. We need priorities to judge those choices.

For the URL shortener, an initial priority order could be:

  1. Correct and highly available redirects
  2. Durable link mappings
  3. Low redirect latency
  4. Reasonable operating cost
  5. 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:

Code
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

First finish this small example: “After successful link creation, a visitor opens the new link immediately.” The expected result is ____. A stale replica could break this because ____. A question to ask before allowing delayed visibility is ____.

Check the guided example

The visitor should redirect to the destination. A replica may not yet contain the new row. Ask whether the product can tolerate a temporary not-found response, and for how long. Our brief says no; later we will keep baseline reads on the primary database.

Choose a simple notification service that can send email and mobile push notifications. Before naming any infrastructure, write:

  1. two essential user-visible behaviors;
  2. two deliberately excluded behaviors;
  3. three measurable quality requirements;
  4. three workload assumptions;
  5. two failure questions;
  6. 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.

Compare with one notification-service brief

Include accepting email/push requests and looking up delivery status; exclude scheduling and marketing campaigns. Example targets: over a day, 99% of valid submissions receive an acceptance response within 300 ms at the API boundary; accepted requests survive an application restart; retries with the same request key within 24 hours create one job. Acceptance means stored for processing, not delivered to a person’s device.

Assume 50 million notifications/day, a 5× peak, and 30 days of delivery history. Ask what happens when a provider times out or the application crashes after accepting a request. Prioritize retaining accepted work over immediate delivery, then latency and cost. Different numbers are acceptable; contradictory promises are not. Did your brief distinguish acceptance from delivery, and did every quality claim have a checkable meaning?

Return to this later

At your next session, explain availability versus durability without looking: could a service be unavailable while all its data is safe? Later in the week, write a brief for a shared reading-list service. Use the same questions, but do not copy the shortener’s requirements. Revisit sooner if you cannot explain a distinction; the schedule is a starting point, not a rule about how quickly everyone learns.

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.