Back to System design
System Design Trade-offs Cheat Sheet
easyEvery system design decision is a trade, and saying which side you took — and what it cost — is most of what separates a senior answer from a confident one. This page is the short list of trades that come up in almost every interview, with the sentence that shows you understand each.
Key Concepts
1
There is no such thing as a free choice, only an appropriate one. Interviewers are not looking for the
"correct" option; they are listening for whether you know what you gave up. "I'll use eventual consistency"
is a weak answer. "I'll use eventual consistency because a stale follower count for two seconds is
invisible, and the alternative costs a cross-region round trip on every write" is a strong one.
There is no such thing as a free choice, only an appropriate one.
2
Name the trade before you are asked about it. Volunteering "the cost of this is X" removes the
interviewer's need to probe, and it is the clearest available signal that you have run systems rather than
only read about them.
Name the trade before you are asked about it.
3
Most trades reduce to four currencies: latency, consistency, cost and complexity. Almost every decision
spends one to buy another. When you get lost in an argument, work out which currency you are spending.
Most trades reduce to four currencies:
4
Beware the trades that are not trades. Some choices are strictly worse and only look balanced: rolling
your own consensus, storing money in floats, retrying non-idempotent operations, caching without a
bounded staleness. Recognising those is as valuable as balancing the real ones.
Beware the trades that are not trades.
5
What the interviewer is probing.
What the interviewer is probing.
6
1. "Give a trade-off you have actually made." Probing: whether this is lived or memorised.
Stalls: "Consistency versus availability." Moves up: a specific one with the context and what it
cost — a named decision with its downside is far more convincing than the abstract pair.
1. "Give a trade-off you have actually made."
7
2. "What does CAP actually say?" Probing: precision, because it is widely misquoted. Stalls:
"Pick two of three." Moves up: under a network partition you choose consistency or availability —
outside a partition it says nothing, which is why PACELC is the more useful framing.
2. "What does CAP actually say?"
8
3. "When is eventual consistency unacceptable?" Probing: judgement. Stalls: "It always
works." Moves up: where a stale read causes real harm — account balances before a transfer,
inventory at checkout, permission checks.
3. "When is eventual consistency unacceptable?"
9
4. "How do you answer a which-would-you-choose question?" Probing: the technique. Stalls:
"Pick the better one." Moves up: name the deciding factor first, then choose — the reasoning is
the answer, and a choice without it scores nothing.
4. "How do you answer a which-would-you-choose question?"
The trades that come up constantly
Strong vs eventual consistency
Buys: correctness under concurrency / lower latency and higher
availability
Costs: a round trip to a quorum / stale reads the app must
tolerate
Say: "Eventual here because a two-second stale count is
invisible, and a quorum write costs 60 ms cross-region." Normalised vs denormalised
Buys: one source of truth, cheap writes / fast reads, no joins
Costs: joins at read time / update fan-out and drift
Say: "Denormalised, because this is read 100x more than written,
and I'll keep the write path fixing all copies." Sync vs async processing
Buys: immediate result, simple errors / responsiveness, buffering
Costs: caller waits for the slowest dependency / eventual
completion the UI must represent
Say: "Async, and the client shows 'processing' -- the alternative
couples checkout latency to the email provider." Cache vs no cache
Buys: latency and origin protection
Costs: staleness, invalidation bugs, a new failure mode
Say: "Cached with a 30 s TTL; a stale price for 30 s is
acceptable, a stale balance is not." Monolith vs services
Buys: simple deploys and local transactions / independent scaling
and teams
Costs: coupled releases / network calls, partial failure,
distributed debugging
Say: "Monolith until the team or the scaling profile forces a
split; the first service to extract is the one with a
different scaling shape." SQL vs NoSQL
Buys: joins, transactions, ad-hoc queries / horizontal writes
Costs: harder horizontal scaling / queries fixed at design time
Say: "PostgreSQL until measured limits; the access pattern here
is not known well enough to fix a partition key." Push vs pull
Buys: low latency, no wasted polls / simple, resilient clients
Costs: connection state and fan-out cost / latency and load
Say: "Push for chat, pull for a dashboard refreshed every
minute." Replication vs sharding
Buys: read scale and redundancy / write scale and dataset size
Costs: no write scale, lag / cross-shard queries, resharding
Say: "Replicas first -- they solve reads without giving up
joins. Shard when writes or size force it.Choices that are not trade-offs
These look like judgement calls and are not:
Rolling your own consensus
The algorithm is describable in a page and unpleasant in the
details. Use etcd, ZooKeeper or a library. Money in floating point
0.1 is not representable. Integer minor units, always. Retrying non-idempotent operations
A retried payment is a second payment. Idempotency key first,
retries second. Caching without bounded staleness
"We'll invalidate on write" plus a missed path equals a stale
value forever. A TTL is the backstop that makes the bug
temporary. Logging secrets "temporarily"
Logs outlive intentions and spread to systems with different
access rules. Dual writes to two datastores
They fail independently. Use an outbox and make one store
authoritative. Unbounded queues
A queue with no limit converts a throughput problem into an
out-of-memory crash plus unbounded latency. Bound it and decide
what to shed. Health checks that never fail
A check that returns 200 without touching a dependency will
report a dead service as healthy.