1. Functional vs. Non-Functional Requirements
Functional requirements describe what the system does — the features a user or client can point to: "a user can post a tweet," "a user can upload a photo," "the service returns search results for a query." They're usually the easy half; most candidates instinctively list them.
Non-functional requirements describe how well the system does it — and they're what actually shape the architecture. Scale (how many users, how much traffic), latency (how fast a response must come back), availability (can it ever go down, and for how long), consistency (can two users briefly see different data), and durability (can data ever be lost) are the five that show up constantly:
Functional:
- A user can submit a long URL and receive a short one back
- Visiting the short URL redirects to the original long URL
- (Optional) A user can see click-count analytics for their link
Non-functional:
- Scale: 100M new short URLs created per month
- Read-heavy: reads (redirects) outnumber writes (new URLs) ~100:1
- Latency: redirect must happen in well under 100ms
- Availability: favor uptime over strict consistency -- a stale click
count is fine, a broken redirect is not
- Durability: a short URL must never silently stop working
Notice what the non-functional list already tells you before you've drawn anything: "read-heavy 100:1" says caching will matter enormously; "favor uptime over strict consistency" says this system leans toward eventual consistency rather than a strongly consistent design that sacrifices availability during a partition — exactly the tradeoff Weeks 9–10 formalize as the CAP theorem. Non-functional requirements aren't a checklist to rush past; they're the constraints that determine which architecture is even a reasonable choice.
In a real interview, non-functional requirements are rarely handed to you — you have to ask. "How many users?" "Read-heavy or write-heavy?" "Is strong consistency required, or is eventual consistency acceptable?" Interviewers are explicitly evaluating whether you ask these questions before designing, not just whether you eventually land on a reasonable architecture.
2. Back-of-Envelope Estimation
The goal of estimation isn't precision — it's getting within an order of magnitude, fast enough to inform a design decision. A handful of numbers, kept in your head or jotted on a whiteboard, is enough to tell you whether a single database can handle this system or whether you need to design for sharding from day one.
Writes (new short URLs):
100,000,000 per month
= 100,000,000 / (30 * 24 * 3600) seconds
≈ 40 writes/second average
Reads (redirects), at a 100:1 read:write ratio:
≈ 40 * 100 = 4,000 reads/second average
Peak traffic is rarely uniform -- a common rule of thumb is
2-3x the average for peak load:
Peak reads ≈ 4,000 * 3 ≈ 12,000 reads/second
Storage, assuming ~500 bytes per URL record (long URL + short
code + metadata), over 5 years:
100,000,000 * 12 months * 5 years = 6,000,000,000 records
6,000,000,000 * 500 bytes ≈ 3 TB over 5 years
12,000 reads/second is a number you can act on immediately: it's far more than one database instance should serve directly, which is exactly the signal that pushes you toward the caching layer from Weeks 6–7 sitting in front of the database. 3 TB over five years, on the other hand, is small enough that sharding for storage volume alone isn't yet justified — the read traffic, not the data size, is this system's real scaling pressure. Getting to that conclusion took four lines of arithmetic, not precise measurement.
A second estimation skill worth memorizing: rough latency numbers for common operations, so you can reason about where time actually goes in a request:
L1 cache reference ~1 ns
Main memory reference ~100 ns
Round trip within same data center ~0.5 ms
Read 1 MB sequentially from SSD ~1 ms
Disk seek ~2-10 ms
Round trip, different continent ~100-150 ms
These numbers are why a cache hit (memory) beats a database read (disk) by several orders of magnitude, and why a service with users on multiple continents needs to think about regional deployment or a CDN (Week 2) rather than serving everyone from one data center — the cross-continent round trip alone can exceed an entire latency budget.
Use round numbers throughout: 100M, not 97.3M; 40 writes/sec, not 38.6. The interviewer is watching whether you can reason at the right altitude, not whether you can do long division under pressure — rounding is a feature of good estimation, not a shortcut you should feel guilty about.
3. Reading & Drawing Architecture Diagrams
A system design diagram is a communication tool before it's anything else — its job is to let someone else follow a request through your system without you narrating every box. A minimal, legible diagram for the URL shortener needs only a handful of components:
[Client] --HTTPS--> [Load Balancer] --> [App Servers] --> [Database]
|
+--> [Cache] (redirect lookups)
Write path: Client -> LB -> App Server -> Database (assign short code, store)
Read path: Client -> LB -> App Server -> Cache (hit) -> return redirect
-> Cache (miss) -> Database -> populate cache
Notice this diagram does three things a good one always does: it names every component with a specific role (not "backend," but "App Servers" doing redirect lookups and short-code assignment), it shows both the write path and the read path separately since they behave very differently under this system's 100:1 read-heavy load, and it's simple enough to draw in under two minutes. A diagram that takes ten minutes to draw is usually a diagram that's trying to show too much detail too early — depth belongs in the discussion that follows the diagram, not crammed into the boxes themselves.
Draw the simplest architecture that could plausibly satisfy the requirements first, then add components explicitly as you justify them: "since reads outnumber writes 100:1, I'd add a cache here" is a far stronger answer than starting with a fully loaded diagram that includes a cache, a queue and three databases before explaining why any of them are needed.
4. A Repeatable Framework for Design Interviews
Every case study in this course, and Weeks 13–14 especially, follows the same four-step shape — internalizing it now means you'll spend your mental effort on the actual design later, not on remembering what to do next:
1. Clarify requirements -- functional AND non-functional (Section 1)
2. Estimate scale -- QPS, storage, bandwidth (Section 2)
3. Sketch a high-level design -- the simplest diagram that fits (Section 3)
4. Dive deep and iterate -- pick 1-2 components and go deep,
discuss tradeoffs, address the interviewer's
follow-up questions
Step 4 is where most of an interview's real signal comes from, and it's also where candidates who skipped Steps 1–2 run into trouble — without clear requirements and a rough scale estimate already established, "why did you choose a cache here?" has no grounded answer to fall back on. Every later module in this course maps onto one or two components you'll go deep on in Step 4: caching (Weeks 6–7), message queues (Week 8), consistency tradeoffs (Weeks 9–10), and rate limiting (Week 11) are exactly the kinds of components a Step 4 deep-dive lands on.
5. Hands-on Exercise
Scope and estimate a pastebin service
Apply this week's four-step framework to a system similar to the URL shortener but with its own twist: users paste text, not URLs, and pastes can expire.
Requirements:
- Write a functional requirements list: what can a user actually do with this service? (Create a paste, view a paste, set an optional expiration.)
- Write a non-functional requirements list, making an explicit assumption for each of: scale (assume 10M new pastes/month), read:write ratio, latency target, and consistency preference — state your reasoning for each assumption in one sentence.
- Do the back-of-envelope math: average writes/sec, average and peak reads/sec, and total storage after 3 years assuming an average paste size of 10 KB.
- Sketch a minimal architecture diagram (text or actual boxes) showing the write path and read path separately.
- Write two sentences identifying which single component you'd want to "go deep" on in Step 4, and why — based on what your estimation numbers actually showed.
Expiring pastes is the twist this system has that the URL shortener didn't — think about what has to happen when a paste's expiration time arrives. Does something actively delete it, or does the read path just check the timestamp and treat it as gone? That single design decision is a preview of tradeoffs you'll formalize more rigorously starting Week 3.
6. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
Why do non-functional requirements matter more to the architecture than functional ones?
Why do non-functional requirements matter more to the architecture than functional ones?
Functional requirements ("a user can post a tweet") could be satisfied by nearly any architecture, including a single server with a single database. It's the non-functional requirements — scale, latency, availability, consistency — that actually rule architectures in or out: a 100M-user read-heavy system and a 100-user internal tool can have identical functional requirements but need completely different designs.
Q2
Why is it acceptable — even expected — to round numbers aggressively during back-of-envelope estimation?
Why is it acceptable — even expected — to round numbers aggressively during back-of-envelope estimation?
The purpose of the estimate is to land in the right order of magnitude fast enough to inform a design decision — whether a single database can handle the load, whether a cache is warranted, whether sharding matters. A precise figure computed slowly provides no more design-relevant information than a round number computed in seconds, so precision beyond the nearest order of magnitude is wasted effort.
Q3
In the URL shortener example, what specifically about the estimated numbers justified adding a cache to the architecture?
In the URL shortener example, what specifically about the estimated numbers justified adding a cache to the architecture?
The 100:1 read:write ratio combined with a peak of roughly 12,000 reads/second is far more read load than a single database should serve directly on every request — that specific number, not a general instinct that "caches are good," is what justifies the design choice. It's the same discipline as Section 4's framework: a component gets added because the numbers demanded it, not by default.
Q4
Why is starting with a minimal architecture diagram and adding components explicitly considered stronger than presenting a fully loaded diagram up front?
Why is starting with a minimal architecture diagram and adding components explicitly considered stronger than presenting a fully loaded diagram up front?
A diagram presented with every component already in place gives the interviewer no evidence that each piece is there for a reason rather than habit or memorized templates. Adding a component out loud and explaining the specific requirement or estimate that justified it demonstrates the reasoning process itself, which is the actual thing being evaluated — the final diagram looks similar either way, but only one approach shows the thinking behind it.