Lesson 03 · Architecture & System Design
How to walk into an unfamiliar system and build an accurate mental model fast — data flow, blast radius, and the one resource that caps everything.
Here's the skill that separates the levels most visibly in a design review:
seniors read code, principals read systems. Hand a senior an unfamiliar
codebase and they'll start at main() and read down. That doesn't scale past a few
thousand lines — and a Principal is routinely dropped into systems with millions, owned
by teams they've never met. The move is different: stop reading the code and start reading the
system — where data flows, what breaks when each piece dies, and what limits growth.
Kleppmann and Riccomini open the new edition of DDIA with exactly this framing: modern
applications are data systems stitched together from parts, and the architecture-level questions
are reliability, scalability, and maintainability — not code style.1
This lesson gives you the five reads that build that mental model in hours, not months.
Ignore the classes; find the state. For every datastore in the system — databases, caches, queues, object storage, that one cron job's CSV — ask three questions: where does this state live, who writes it, and who reads it? Then trace one real write end-to-end: a user clicks "place order" — which services touch it, which stores does it land in, and in what order? Data outlives code: services get rewritten every few years, but the data and its flow are the system's skeleton.1 A boxes-and-arrows sketch of that flow — one box per store and service, one arrow per read or write — is worth more than a week of reading source, and it's the artifact this lesson's lab produces.
Next, find where the system is cut: the API contracts, message schemas, and database tables that multiple teams depend on. Martin Fowler's working definition of architecture is "the important stuff — whatever that is": the decisions that are expensive to change and that expert developers on the project agree really matter.2 Boundaries are precisely that stuff. A field in a shared event schema is a promise to every consumer you've never met; renaming it is an org-level negotiation, while renaming a private method is a Tuesday. When you read a system, mark each boundary with two labels: what is promised (the contract) and who breaks if the promise breaks (the consumers). That second label is your first taste of blast radius.
Now stress-test the model: walk your diagram and kill each dependency in your head. DDIA draws the crucial distinction — a fault is one component deviating from spec; a failure is the system as a whole no longer delivering service — and reliable systems are the ones that keep faults from becoming failures.1 The AWS Well-Architected reliability pillar operationalizes the same idea: design for the failure of any single component, know your recovery path, and test it.3 The Principal-level tell is specificity. Compare the two columns:
| Dependency dies | Vague reading | Principal reading — with blast radius |
|---|---|---|
| Redis cache | "We'd have cache issues" | "Sessions live only in Redis — every user is logged out, and the DB inherits the full read load, which may take it down too" |
| Message queue | "Messages get delayed" | "Orders still accept, but stock-sync and emails lag; past the 2-hour retention window we silently lose events" |
| Payment API | "Payments would fail" | "Checkout blocks outright — nothing queues the attempt, carts aren't persisted, so revenue stops and retries are lost" |
Every system has exactly one resource that caps its throughput at any given moment — the bottleneck. Everything else has headroom; that one thing doesn't, and scaling anything else is wasted effort. DDIA's scalability question is the right lens: describe the current load precisely (writes per second, read/write ratio, working-set size), then ask what happens when one of those parameters grows.1 Usually the answer points at a single spot — the primary database that all writes funnel through, the one synchronous call to a rate-limited third party, the queue consumer that's single-threaded. Ask the team "what would you have to fix if traffic tripled next month?" — the answer names the bottleneck, and whether they have an answer tells you how well they've read their own system.
The last read is the sneakiest: every system rests on assumptions that were true at design time and are quietly checked nowhere. "Payloads fit in memory." "There's only one writer to this table." "That job always finishes before midnight." "Region us-east-1 is up." These are load-bearing assumptions — invisible while true, catastrophic when they stop being true, because no alert fires and no test fails. The question that surfaces them is one of the highest-leverage questions a Principal asks in any review: "What is this design assuming that nobody is checking?" Asking it well is also how you build credibility fast in a system you didn't write — you're not criticizing anyone's code; you're reading the physics.
This lesson's artifact is a one-page system map of a real system at work — one you touch weekly but didn't design. It doubles as promotion evidence ("understands systems beyond their team") and as your warm-up for every system-design interview. One page, four sections:
Feedback loop: bring the map back to me in chat and I'll review it against a Principal-level rubric — does the diagram show data flow rather than an org chart of services, are the failure modes specific ("if Redis dies, sessions drop", not "cache issues"), and is the bottleneck claim backed by evidence rather than folklore. Keep the map in your evidence trail; Lesson 12 folds it into your promotion packet, and Lesson 06's design lab builds directly on it.
Three scenarios. Apply the five reads — don't scroll up. Wrong picks stay live.
Scenario A
You've just joined a team that owns a 12-service order platform. In two weeks you're expected to weigh in on its architecture. You have maybe six focused hours for orientation. Where do they go?
Scenario B
In a design review, an engineer's reliability section reads: "If the cache goes down we may see some degradation, and the queue could cause delays under load." You're the Principal in the room. What's the highest-value response?
Scenario C
Checkout latency climbs every peak. The team doubled the stateless app servers last quarter — no improvement — and now proposes doubling them again. Metrics show app CPU at 40%, database write IOPS pinned at its provisioned ceiling. Your call?
Hand-picked follow-ups. None are required — the primary source above comes first.