Stating a trade-off
We will X, it costs Y, we accept because Z, we would revisit if W — and the condition for revisiting is what almost nobody says.
Every system design question has many acceptable answers and one unacceptable behaviour: choosing without saying what it costs. That is what the interview is measuring, and it is also what a design document is for.
A trade-off is not a hedge. It is a decision, plus the price, plus the condition under which you would decide differently.
The shape
We will X. This costs us Y. We accept that because Z. We would revisit if W.
Applied:
We will serve the feed from a fan-out-on-write cache. This costs us a write amplification of roughly 200× for an average user, and minutes of staleness for followers of very large accounts. We accept it because reads outnumber writes by about a thousand to one and read latency is the product. We would revisit if the top-percentile follower count grew past about a million, where the write cost stops being bounded.
Four sentences. A decision, a cost stated in numbers, a reason grounded in the workload, and a named condition that would change the answer. That last part is what separates an engineer from someone repeating an architecture they read about — it demonstrates you know why it is right rather than that it is.
Say the number, not the adjective
"Faster", "more scalable", "cleaner" are not costs. They are opinions with no units.
- Not "a cache makes it faster" — "a cache takes the p99 from 200 ms to 5 ms, at the cost of up to 60 seconds of staleness".
- Not "sharding scales better" — "sharding gets us past one machine's write throughput, and it costs us cross-shard transactions, which we no longer support".
- Not "queues decouple" — "the queue means the caller returns in 10 ms instead of 2 s, and the work now completes some time later, which the user has to be told".
You rarely need precise numbers. You need order of magnitude and a unit, which is what the estimation lesson is for. "Tens of milliseconds", "a few gigabytes a day", "single-digit percentage" are all fine. "Fast" is not.
The trade-offs that come up every time
Six axes. Nearly every decision in a design sits on one of them, and knowing the pairs means you can say the cost without inventing it on the spot.
| You gain | You give up |
|---|---|
| consistency | availability during a partition, or latency — CAP and PACELC |
| latency (a cache, a read replica) | freshness, and a cache to invalidate |
| write throughput (sharding, async) | cross-shard transactions, ordering, simple queries |
| availability (replicas, retries) | cost, and duplicate work you must make idempotent |
| flexibility (a generic schema, a queue in the middle) | the ability to reason about it, and often performance |
| simplicity | scale headroom you may never need |
The last row deserves its own sentence, because it is the one candidates skip: simplicity is a thing you are trading away, and trading it for scale you do not have is the most common bad decision in this subject. A design that says "one Postgres, because ten thousand writes a second is four percent of what it can do" is a stronger answer than one that shards preemptively — if you say the number.
What makes an answer weak
- A stack with no reasoning. "Kafka, Redis, Cassandra, Elasticsearch." Every one of those may be right, and naming them is not a design. The question is what each solves that the previous thing could not.
- Refusing to choose. "It depends" is true and it is not an answer. Choose, then say what it depends on.
- A cost nobody would accept. If the price you name is one no sensible team would pay, either the decision is wrong or you have not understood the cost.
- No condition for revisiting. A decision with no expiry is a decision that will be wrong silently later.
- Inventing precision. "We will need 14,338 requests per second" from nothing is worse than "call it ten thousand". The estimation lesson is explicit about this.
Writing it down, which is the same skill
The interview version and the document version are the same four sentences. An architecture decision record — docs/adr/ in this repository — is exactly that shape: context, decision, consequences.
That framing is why an ADR is worth writing even when nobody asks. Six months later the question is never what was decided; it is why, and would we still. A decision recorded without its cost cannot be revisited, because nobody can tell whether the conditions changed.