Functional vs non-functional requirements, why "it depends" is the correct answer, and how to make it specific enough to build from.
Module F-1 — What Is System Design? Requirements, Constraints, and Trade-offs
What this module covers: "Design Twitter" is not a task. It's a prompt with roughly a hundred unstated decisions inside it, and the difference between a good system designer and a bad one is almost entirely about which of those decisions they surface before writing any code. This module covers what system design actually is as an activity, functional vs non-functional requirements, the four numbers that change every subsequent answer, the constraints that are handed to you rather than chosen, and why "it depends" is the correct response — plus how to make it specific enough to build from. It also establishes the rule the rest of this course follows: no recommendation without its cost named.
System Design Is Deciding What to Regret
Every system is a set of choices, and every choice closes doors. Pick Postgres and you've decided that a 500-node write cluster will be somebody's painful migration later. Pick Cassandra and you've decided that your first "show me all orders over $500 from last Tuesday, sorted by customer name" report will be a genuine engineering project rather than a five-minute query. Neither choice is wrong. Both are decisions about which future problems you'd rather have.
This is why system design interviews and system design documents both feel slippery to engineers coming from feature work. In feature work there's usually a correct answer — the button either submits the form or it doesn't. In system design there is no correct answer, only answers that are correct given a set of requirements, and the requirements are the part nobody hands you.
Analogy: System design is writing a building brief, not drawing a building. An architect who's asked to "design an office" and immediately starts drawing has skipped the only part that matters: how many people, doing what work, in what climate, on what budget, with what expansion plans over ten years. A 40-person design studio and a 40-person call centre are the same headcount and completely different buildings. "Design Twitter" is "design an office."
Why this matters in production: the most expensive engineering failures are rarely bad code. They're systems that were built correctly against requirements nobody wrote down, and then met real requirements that turned out to be different. A search feature built on LIKE '%term%' is correct code — it works, it's tested, it ships. It becomes an incident the day the table crosses a few million rows, because nobody ever asked "how many products will be in the catalogue in eighteen months, and how fast does search need to be?" The bug wasn't in the query. It was in the brief.
Functional vs Non-Functional Requirements
The single most useful split in system design is between what the system does and how well it has to do it.
Functional requirements are behaviours. A user can post a message. A user can follow another user. A user sees a timeline of posts from people they follow. These are the things a product manager writes, the things you'd demo, the things that appear in acceptance criteria. They tell you what to build.
Non-functional requirements are qualities. The timeline loads in under 300ms at the 99th percentile. The system stays available if one datacentre fails. A posted message is never lost once acknowledged. Data for EU users doesn't leave the EU. These tell you how to build it — and they are almost the entire content of system design.
Here's the thing that surprises people: the functional requirements for a timeline feature fit in a sentence and can be implemented in an afternoon. It's the non-functional requirements that generate the entire architecture.
That function satisfies the functional requirement completely. It is also the version that works for 10,000 users and falls over at 10 million, because a join-and-sort across every post by everyone you follow gets more expensive as both the follow graph and the post table grow. Everything in Module A-14 — fan-out on write, the celebrity problem, precomputed timelines, cache hierarchies — exists to satisfy non-functional requirements that this query cannot: p99 under 300ms, at 100 million users, with a 60:1 read/write ratio.
The lesson to carry forward: when someone says "the design is simple," they are almost always describing the functional requirements. The design is simple. The non-functional requirements are what make it hard.
The Four Numbers That Change Every Answer
Most system design arguments are two people reasoning correctly from different unstated assumptions. You can collapse the majority of them by pinning down four numbers first.
1. Scale — how many, and how fast is it growing?
Not "a lot." A number. 10,000 users or 10 million users are different systems, and 10 million users growing 5% a month is a different system again from 10 million users flat for three years. Growth rate determines whether you design for today's load with room to react, or design the sharding scheme now because you won't get a chance to retrofit it calmly.
2. Read/write ratio — which direction is the traffic?
A social feed is read-heavy, often 100:1 or worse: every post is written once and read thousands of times. An IoT telemetry ingest is write-heavy: millions of writes, read occasionally by a dashboard. A chat system is roughly balanced. This single ratio decides whether caching is your primary tool (read-heavy — Module F-12 onward), whether you need a write-optimised storage engine (write-heavy — Module P-2), and whether read replicas will help at all (they help reads; they do nothing for a write bottleneck, as Module P-5 covers).
3. Consistency tolerance — how stale can a read be before it's a bug?
This is the question most likely to be skipped and most likely to determine the architecture. "How long after I post can my follower not see the post before someone files a ticket?" For a Twitter-like timeline, a few seconds is genuinely fine. For a bank balance after a transfer, zero seconds is fine — and note that "zero" is a much more expensive number, because it rules out the async replication that made the timeline cheap. Modules P-10 and P-11 are entirely about paying for this number honestly.
Sign in to keep reading
The rest of this module is free — sign in with Google to unlock it and track your progress.
Sign in & RegisterDiscussion
0Join the discussion