System Design & Deployment Patterns

A mechanism-first course on scaling, caching, data, reliability and deployment — for interview prep and for systems you actually have to run.

01 · Foundations

The system design interview mental model

Every system design exercise — whether it's an interview or a real design doc — falls apart in the same place: someone starts drawing boxes before anyone agrees what the system is supposed to do, at what scale, and under what constraints. The discipline that separates a strong design from a shaky one is almost entirely upstream of the architecture: clarify requirements, do the arithmetic, and only then let the numbers tell you which trade-offs are even on the table.

Functional vs. non-functional requirements

Functional requirements describe what the system does — the operations a user or client can invoke, and their expected behavior. Non-functional requirements describe the qualities the system must have while doing that — scale (how many users, how much data, how much traffic), latency (p50/p99 targets), availability (can it tolerate downtime, and how much), consistency (can reads be briefly stale), and durability (can data ever be lost). Non-functional requirements are the ones that actually drive architecture: two systems with identical functional requirements — "let a user post a message" — produce completely different designs if one needs to serve 500 requests a day and the other needs to serve 500,000 a second with a 200ms p99.

A few clarifying questions worth asking for almost any "design X" prompt, because the answers change the design:

Back-of-envelope estimation as a discipline

Estimation isn't a box-ticking ritual before the "real" design work — it's the mechanism by which requirements become constraints you can design against. The method is always the same three calculations: traffic (QPS), storage growth, and bandwidth, derived from a small number of assumed inputs using simple arithmetic. A few approximations make the mental math fast and are worth memorizing:

// time 1 day ≈ 86,400 seconds ≈ 10^5 seconds (good enough for order-of-magnitude math) 1 year ≈ 3.15 × 10^7 seconds // data size, base-2 approximations 1 KB ≈ 10^3 bytes 1 MB ≈ 10^6 bytes 1 GB ≈ 10^9 bytes 1 TB ≈ 10^12 bytes
Illustrative example

Say we're estimating for a hypothetical service with 10 million daily active users (DAU), where each user performs 20 read actions and 2 write actions per day on average, each request/response pair is roughly 2 KB, and each written record is roughly 1 KB. These numbers are illustrative, not observed — the point is the method, which works the same way regardless of the actual inputs.

// (a) QPS from DAU and actions/user/day reads/day = 10,000,000 users × 20 = 200,000,000 writes/day = 10,000,000 users × 2 = 20,000,000 avg read QPS = 200,000,000 / 86,400 ≈ 2,315 QPS avg write QPS = 20,000,000 / 86,400 ≈ 232 QPS // traffic is never uniform across the day — plan capacity for peak, not average. // a common starting assumption (illustrative, tune with real traffic curves) is peak ≈ 2-3× average peak read QPS ≈ 2,315 × 3 ≈ ~7,000 QPS // (b) storage growth per year bytes/year = writes/day × record size × 365 = 20,000,000 × 1,000 bytes × 365 ≈ 7.3 × 10^12 bytes ≈ ~7.3 TB / year // add index overhead (often 20-50% on top of raw row size) and replication factor (e.g. 3x for durability) // → realistic provisioning is closer to 7.3 TB × 1.3 × 3 ≈ ~28 TB/year of raw disk // (c) bandwidth from request/response size and QPS read bandwidth = 2,315 QPS × 2 KB × 8 bits/byte ≈ 37 Mbps sustained, ~110 Mbps at peak

The value of doing this isn't the specific numbers — it's what they rule in or out. A ~7,000 peak QPS read path with a 2-3x read:write skew says "you need a cache and probably read replicas, but you do not need to shard on day one." A p99 latency budget of 10ms says "no synchronous call to a service in another region can be in the hot path, full stop" — the speed of light alone (roughly 60-70ms round-trip cross-continent over real network paths) makes that arithmetically impossible before any processing time is added. This is the actual purpose of estimation: it converts vague scale talk into hard constraints that eliminate whole categories of design, before you've drawn a single box.

Back-of-envelope capacity calculator

Interactive

Plug in rough numbers for a hypothetical service and watch the QPS, storage, and bandwidth arithmetic compute live — the same three calculations from above, worked on your inputs.

02 · Foundations