System Design Terminology - The Fine Distinctions

Prerequisites: none — start here if you’re new, or use it as a pre-interview refresher Used in: every design on this site. This page is the vocabulary layer underneath all of them.


Why this page exists

Interviewers rarely ask “what is sharding?” They ask “what’s the difference between partitioning and sharding?” — because the difference reveals whether you learned the concept or memorized the word.

These questions take 20 seconds to answer and are heavily weighted. A crisp answer signals you’ve operated real systems. A vague one (“umm, they’re kind of the same thing?”) undoes ten minutes of good design work.

Each entry below is: the distinction, then the one-liner you say out loud.


1. Data & Storage

Partitioning vs Sharding

This is the most-asked distinction in the entire list.

  Partitioning Sharding
Definition Splitting one logical dataset into smaller pieces Partitioning across separate machines
Scope Can be within a single database/server Always spans multiple servers
Goal Manageability, query pruning, cheaper archival Scale beyond one machine’s CPU/RAM/disk
Example Postgres PARTITION BY RANGE (created_at) — one server, 12 monthly child tables 4 Postgres instances, users 0-25M on box 1, 25-50M on box 2
Coordination cost None (single node handles it) High (routing layer, cross-shard joins, distributed txns)

Say this: “Sharding is a type of partitioning — specifically horizontal partitioning where the partitions live on different machines. All sharding is partitioning; not all partitioning is sharding. If I split a table by month but it’s still one Postgres instance, that’s partitioning, not sharding — I get query pruning and cheap drops of old data, but zero extra write throughput.”

The follow-up trap: “So when do you partition without sharding?” → “Time-series data. Partition an events table by day so DROP PARTITION replaces a slow DELETE, and queries with a date filter only scan one child table. Same server, big win, none of the distributed-systems pain.”

⚠️ Careful — “partition” means three different things:

Context What “partition” means
Databases A subset of a table’s rows/columns
CAP theorem A network partition — nodes can’t talk to each other
Kafka The unit of parallelism and ordering within a topic

If an interviewer says “partition,” and it’s ambiguous, ask. That’s a point in your favor, not against.

Horizontal vs Vertical Partitioning

  Horizontal (rows) Vertical (columns)
Splits Rows across partitions Columns across partitions
Each piece has Same schema, different rows Different schema, same rows
Example Users A-M / N-Z users (id, name, email) + user_profiles (id, bio, avatar_blob)
Motivation Volume of rows Wide rows, hot vs cold columns, different access patterns

Say this: “Horizontal = same columns, fewer rows each. Vertical = same rows, fewer columns each. Sharding is horizontal partitioning across machines. Vertical partitioning is what you do when 3 columns are read on every request and 20 are read once a month.”

Replication vs Sharding

  Replication Sharding
Each node holds The same data (full copy) A different subset
Solves Read scale, availability, durability Write scale, storage capacity
Node loss means Nothing (other copies exist) That slice of data is offline
Cost Storage × N Coordination complexity

Say this: “Replication copies, sharding divides. They’re orthogonal and production systems use both: shard for write capacity, replicate each shard 3× so a dead node doesn’t lose a slice of your data.”

More storage distinctions

Pair The distinction
Normalization vs Denormalization Normalize = one fact in one place, join on read (write-optimized, storage-efficient). Denormalize = duplicate the fact into every read shape (read-optimized, you own the consistency problem).
OLTP vs OLAP OLTP = many small point reads/writes, milliseconds, row-oriented (Postgres). OLAP = few huge aggregate scans, seconds-to-minutes, column-oriented (Redshift, BigQuery, Snowflake).
Row store vs Column store Row = all columns of one record contiguous → fast “give me this user.” Column = all values of one column contiguous → fast “average this column over 1B rows,” and 10× better compression (similar values adjacent).
B-Tree vs LSM Tree B-Tree = update in place, read-optimized, lower write amplification for random writes of small size (Postgres, MySQL). LSM = append to memtable, flush to sorted files, compact in background → write-optimized, reads may check multiple levels (Cassandra, RocksDB, LevelDB).
Clustered vs Non-clustered index Clustered = the index is the table’s physical order (one per table; InnoDB primary key). Non-clustered/secondary = separate structure pointing at rows (many per table).
Covering index vs regular index Covering index contains every column the query needs, so the DB never touches the table (“index-only scan”). Regular index forces a second lookup per matched row.
Primary vs Unique vs Foreign key Primary = unique + NOT NULL + one per table + usually clustered. Unique = unique, may allow one NULL, many per table. Foreign = a pointer into another table’s key, enforces referential integrity.
Index vs Materialized view Index accelerates access to live rows. Materialized view stores a precomputed result set that goes stale until refreshed.
Data lake vs Warehouse vs Lakehouse Lake = raw files, schema-on-read, cheap, any format (S3 + Parquet). Warehouse = modeled, schema-on-write, expensive, SQL-fast. Lakehouse = warehouse engine over lake storage (Delta, Iceberg, Hudi).
ETL vs ELT ETL = transform before loading (transform tier does the work; classic warehouse). ELT = load raw, transform inside the warehouse with SQL (modern, because warehouse compute got cheap).
Schema-on-write vs schema-on-read On-write = DB rejects bad data at insert (safe, rigid). On-read = anything goes in, reader interprets (flexible, you find the bad data at 3am).
Block vs File vs Object storage Block = raw disk, you bring the filesystem, lowest latency (EBS). File = hierarchical POSIX shared mount (EFS, NFS). Object = flat key→blob over HTTP, infinite scale, no partial writes (S3).
Snapshot vs Backup vs Replica Snapshot = point-in-time copy, usually same system, fast restore. Backup = independent copy, offsite, survives the system being deleted. Replica = live copy, milliseconds behind — a replica is not a backup, because DROP TABLE replicates too.
Soft vs Hard delete Soft = set deleted_at, row stays (audit, undo, restore — but every query needs the filter and GDPR gets awkward). Hard = row is gone.
Write / Read / Space amplification Write amp = bytes written to disk ÷ bytes the app wrote (LSM compaction inflates this). Read amp = disk reads per logical read. Space amp = bytes stored ÷ bytes of live data. You can optimize two, never all three.
Tombstone vs Compaction Tombstone = a marker meaning “this key is deleted” (needed so the delete replicates and doesn’t get resurrected by an older copy). Compaction = background merge of sorted files that finally drops tombstoned data.
Hot vs Warm vs Cold storage Hot = accessed constantly, expensive per GB, free-ish per read (S3 Standard, SSD). Warm = weekly-ish (S3 IA). Cold = archival, cheap per GB, slow and costly to read (Glacier — minutes to hours to restore).
Cursor vs Offset pagination OFFSET 10000 makes the DB count and discard 10,000 rows and skips/duplicates items if the list mutates. Cursor (keyset) pagination — WHERE id > last_seen ORDER BY id LIMIT 20 — is O(limit) and stable. Use cursors for infinite scroll; offset only for small admin tables with page numbers.

2. Consistency & Distributed Systems

Consistency (CAP) vs Consistency (ACID)

Same word, completely different meaning. Interviewers love this one.

  C in CAP C in ACID
Means All replicas return the same latest value The transaction preserves database invariants (constraints, FKs, balances sum correctly)
About Replication across nodes Correctness of one transaction on one node
Enforced by Consensus, quorums, sync replication Your constraints + the app’s own logic

Say this: “The C in ACID isn’t the C in CAP. ACID-C means ‘this transaction doesn’t violate my invariants’ — it’s really an application-level property the DB helps enforce. CAP-C means linearizability across replicas. Conflating them is why people say ‘ACID databases are CP,’ which is imprecise.”

Linearizability vs Serializability

  Linearizability Serializability
Unit A single object/register A set of operations in a transaction
Guarantee Every op appears to happen at one instant, in real-time order Transactions produce a result equal to some serial order
Real-time order Required Not required — the serial order can differ from wall-clock order
Example system etcd, ZooKeeper (single key) Postgres SERIALIZABLE (SSI)

Say this: “Linearizability is a recency guarantee on one object; serializability is an isolation guarantee across many objects. Both together is ‘strict serializability’ — what Spanner gives you, and why it needs atomic clocks and GPS.”

Quorum arithmetic (know the formula cold)

N = replicas,  W = replicas that must ack a write,  R = replicas read

W + R > N   →  read set and write set must overlap → you read the latest write
W = N, R = 1  →  fast reads, slow/fragile writes
W = 1, R = N  →  fast writes, slow reads
N=3, W=2, R=2 →  the standard balanced choice, tolerates 1 node loss

Say this: “With N=3, W=2, R=2 the read and write quorums must share at least one node, so a read always sees the newest acknowledged write. That’s how Dynamo-style stores offer tunable consistency: same cluster, ONE for a feed, QUORUM for a balance.”

More distributed-systems distinctions

Pair The distinction
Availability vs Reliability vs Durability Available = responding right now (%uptime). Reliable = responding correctly over time (MTBF). Durable = once acknowledged, the data survives — S3’s 11 nines is durability, not availability.
Fault tolerance vs HA vs DR Fault tolerance = keeps working through a component failure, no visible impact. HA = minimizes downtime, small blip allowed (seconds of failover). DR = recovering from losing a whole region/datacenter (minutes-to-hours, measured by RPO/RTO).
Failover vs Switchover Failover = unplanned, automatic, triggered by a failure. Switchover = planned, human-initiated (maintenance). “Switchover” is the one you can test on a Tuesday.
Split-brain vs Network partition Partition = the network fault (cause). Split-brain = two nodes both believing they’re leader and both accepting writes (consequence). Fix: quorum-based election + fencing tokens.
Active-active vs Active-passive Active-active = all regions serve traffic (better utilization, needs conflict resolution). Active-passive = standby idle until failover (simpler, you’re paying for idle capacity and your failover path is untested unless you drill it).
Leader-follower vs Multi-leader vs Leaderless Single leader = one writer, no write conflicts, leader is a bottleneck + SPOF (Postgres, MySQL). Multi-leader = writes anywhere, conflicts are now your problem (multi-region, CouchDB). Leaderless = any replica takes writes, quorums + read repair fix divergence (Dynamo, Cassandra).
Sync vs Async vs Semi-sync replication Sync = commit waits for all replicas (zero data loss, worst latency, one slow replica stalls writes). Async = commit returns immediately (fast, lose the tail on failover). Semi-sync = wait for one replica (the pragmatic default).
Logical vs Physical replication Physical = ship byte-level WAL, replica is a block-identical clone, same version required. Logical = ship row-level changes, so you can replicate one table, across versions, into a different system (this is how CDC works).
Consensus vs Coordination Consensus = N nodes agreeing on one value despite failures (Raft, Paxos). Coordination = the services built on it — locks, leader election, config, membership (ZooKeeper, etcd). Consensus is the algorithm; coordination is the product.
Raft vs Paxos vs ZAB Same guarantee, different ergonomics. Paxos = original, notoriously hard to implement. Raft = designed for understandability, explicit leader + log matching (etcd, Consul). ZAB = ZooKeeper’s, optimized for primary-order broadcast. Interview answer: “Raft, because it’s understandable and every modern system uses it.”
2PC vs Saga 2PC = blocking, synchronous, atomic across resources, coordinator crash freezes participants holding locks. Saga = sequence of local transactions + compensating actions, no locks, no atomicity — you get intermediate states other readers can see. Microservices use sagas because 2PC across HTTP is a liveness disaster.
Idempotent vs Commutative Idempotent = doing it twice = doing it once (SET x=5). Commutative = order doesn’t matter (+1 then +2 = +2 then +1). Retries need idempotence; out-of-order delivery needs commutativity. They’re different problems.
At-least-once + idempotent = “exactly-once” True exactly-once delivery is impossible over an unreliable network. Exactly-once processing is achievable: at-least-once delivery + a dedupe key or idempotent write. Say it this way and you’ll sound like you’ve shipped it.
CRDT vs LWW vs Vector clocks LWW = keep the highest timestamp, silently drops a write (clock skew makes this worse). Vector clocks = detect concurrency, then hand the conflict to you (or the app). CRDT = data types that mathematically converge with no conflict resolution needed (counters, sets, sequences — Google Docs, Redis CRDT, Automerge).
Anti-entropy vs Read repair vs Hinted handoff Anti-entropy = background full comparison via Merkle trees. Read repair = fix divergence opportunistically when a read notices it. Hinted handoff = a live node holds writes destined for a dead node and replays them on recovery. Dynamo-style systems use all three.
Gossip vs Heartbeat Heartbeat = directed “I’m alive” to a known monitor; O(N) fan-in, monitor is a bottleneck. Gossip = randomized peer-to-peer rumor spreading; scales to thousands of nodes, converges in O(log N) rounds, no central monitor.
Lock vs Lease vs Fencing token Lock = mutual exclusion, no time bound (a crashed holder blocks forever). Lease = a lock with an expiry (progress guaranteed, but the holder may not notice it expired). Fencing token = monotonic number handed out with the lease, and the storage layer rejects lower numbers — the only thing that actually makes distributed locking safe.
Optimistic vs Pessimistic locking Optimistic = don’t lock, check a version on write, retry on conflict (great when conflicts are rare). Pessimistic = SELECT ... FOR UPDATE, block others up front (right when contention is high or retries are expensive).
Wall clock vs Monotonic vs Logical vs Hybrid Wall clock (System.currentTimeMillis) can jump backwards via NTP — never use it to measure elapsed time or order events. Monotonic = only moves forward, meaningless across machines, correct for durations. Logical (Lamport/vector) = orders events causally with no clocks. Hybrid Logical Clock = physical time + logical counter, so timestamps are both human-readable and causally correct (CockroachDB).
Ordering: total vs causal vs per-key Total = every node sees every event in the same order (expensive, needs consensus). Causal = related events ordered, unrelated ones may differ (usually sufficient). Per-key/per-partition = Kafka’s model, and 95% of designs only ever need it.

3. Performance & Reliability Vocabulary

Latency vs Response time vs Service time

Term What it measures
Service time Time the server spent actually working on the request
Latency Strictly: time a request spends waiting (queueing, network). Loosely used as a synonym for response time.
Response time What the client experiences: network + queueing + service + serialization

Say this: “Response time is what the user feels; service time is what my server logs. The gap between them is queueing — and under load, queueing dominates, which is why p99 explodes long before CPU hits 100%.”

Latency vs Throughput

They’re not opposites, and improving one often hurts the other.

Latency    = time per operation          (seconds/op)      → lower is better
Throughput = operations per unit time    (ops/second)      → higher is better

Batching:   throughput ↑↑,  latency ↑    (wait to fill the batch)
Pipelining: throughput ↑,   latency ~    (overlap work)
Adding replicas: throughput ↑, latency ~ (until coordination costs bite)

Little’s Law — worth memorizing:

Concurrency (L) = Arrival rate (λ) × Response time (W)

10,000 req/s × 0.2s avg = 2,000 in-flight requests
→ so your thread pool / connection pool must hold 2,000, or you queue

Say this: “Little’s Law is how I size pools. At 10K rps with 200ms responses I have 2,000 requests in flight, so 200 threads across 10 boxes with a 20-deep connection pool each. If latency doubles, concurrency doubles — that’s how a slow downstream causes an unrelated thread-pool exhaustion outage.”

Percentiles

Term Meaning
p50 (median) Half of requests are faster than this. Says nothing about pain.
p99 1 in 100 requests is slower. At 10K rps that’s 100 users per second having a bad time.
p99.9 Usually your biggest customers — they make the most requests, so they hit the tail most.
Average Actively misleading; one 30s timeout hides in a sea of 5ms requests.

⚠️ You cannot average percentiles. The mean of two servers’ p99s is not the fleet p99. You need histograms/t-digest merged, then compute the percentile.

Tail amplification: if a request fans out to 10 services in parallel and each has a 1% slow tail, the odds none of them is slow is 0.99¹⁰ ≈ 90% — so ~10% of your requests hit a tail. Fan-out turns a rare p99 into a common p90.

Say this: “I’d SLO on p99, not average, and remember that fan-out amplifies tails — 10 parallel calls at p99=1% means one in ten user requests is slow. Mitigations: hedged requests, request-level timeouts below the client’s, and fewer sequential hops.”

More performance & reliability distinctions

Pair The distinction
QPS vs TPS vs RPS vs Concurrency QPS/RPS = queries or requests per second (rate). TPS = transactions per second (a transaction may be several queries). Concurrency = how many are in flight simultaneously — a rate without a latency tells you nothing about load.
Bandwidth vs Throughput vs Goodput Bandwidth = theoretical max capacity. Throughput = what you actually achieve. Goodput = throughput excluding retransmits, headers, and protocol overhead — the payload the app actually got.
Scalability vs Performance vs Efficiency vs Elasticity Performance = fast for one user. Scalability = stays fast as load grows (and cost grows no worse than linearly). Efficiency = performance per dollar/watt. Elasticity = scales automatically, both directions, quickly.
Concurrency vs Parallelism Concurrency = dealing with many things at once (structure — an async event loop is concurrent on 1 core). Parallelism = doing many things at once (execution — needs multiple cores).
Blocking vs Non-blocking, Sync vs Async Blocking = the calling thread waits and is unusable. Async = you’re notified on completion (callback/future). One thread can serve 10K connections if I/O is non-blocking — that’s the whole point of Node/Netty/epoll.
Process vs Thread vs Coroutine Process = own memory, isolated, expensive (~MBs). Thread = shared memory, cheaper (~1MB stack), OS-scheduled. Coroutine/virtual thread = user-space scheduled, ~KBs, millions feasible (Go goroutines, Java virtual threads).
CPU-bound vs I/O-bound vs Memory-bound Diagnose before you scale: CPU-bound → more cores/better algorithm. I/O-bound → concurrency, caching, batching (more cores do nothing). Memory-bound → you’re thrashing cache lines or swapping; more RAM or better data layout.
Head-of-line blocking One stuck item at the front stalls everything behind it. Occurs in HTTP/1.1 pipelines, TCP (a lost segment stalls all HTTP/2 streams on that connection), single-partition Kafka consumers, and FIFO queues. Fix: independent streams (HTTP/3), more partitions, or a parking-lot queue.
Backpressure vs Load shedding vs Rate limiting vs Throttling Backpressure = tell the producer to slow down (bounded queue, TCP window) — preserves work. Load shedding = drop excess requests to protect the system (reject with 503) — sacrifices work to stay alive. Rate limiting = a policy cap per client (fairness/billing). Throttling = slowing rather than rejecting.
Thundering herd vs Cache stampede vs Retry storm Thundering herd = N waiters all wake for one event. Cache stampede = a hot key expires and every request rebuilds it against the DB. Retry storm = failure → everyone retries → more failure (fix with exponential backoff plus jitter, retry budgets, and circuit breakers).
Circuit breaker vs Bulkhead vs Timeout vs Retry Timeout = bound one call. Retry = try again (dangerous without backoff/budget). Circuit breaker = stop calling a failing dependency entirely for a while, fail fast. Bulkhead = isolate resources per dependency so one slow downstream can’t consume every thread. Real systems need all four.
Fail fast vs Fail open vs Fail closed vs Graceful degradation Fail fast = error immediately instead of hanging. Fail open = on failure, allow the request (availability first — a rate limiter should usually fail open). Fail closed = on failure, deny (security first — authz must fail closed). Graceful degradation = serve a reduced experience (stale cache, no recommendations) instead of an error page.
SLI vs SLO vs SLA vs Error budget SLI = the measurement (“% of requests <300ms”). SLO = your internal target (99.9%). SLA = the contract with money attached, always looser than the SLO. Error budget = 100% − SLO; spend it on releases, and freeze deploys when it’s exhausted.
MTBF vs MTTF vs MTTD vs MTTR MTBF = mean time between failures (repairable). MTTF = mean time to failure (non-repairable, e.g. a disk). MTTD = time to detect. MTTR = time to repair. Availability = MTBF / (MTBF + MTTR) — halving MTTR improves availability as much as doubling MTBF, and is usually far cheaper.
RPO vs RTO RPO = how much data you can lose (backup frequency). RTO = how long you can be down (recovery speed). “RPO 5 min, RTO 1 hour” = 5-minute log shipping + a restore runbook you’ve actually rehearsed.
Availability nines 99% = 3.65 days/yr. 99.9% = 8h 46m/yr (43m/month). 99.99% = 52m/yr (4m 23s/month). 99.999% = 5m 15s/yr (26s/month). Note: 5 nines is less than one failed deploy per year — you cannot get there with human-in-the-loop recovery.
Serial availability multiplies 5 dependencies at 99.9% each in the critical path = 0.999⁵ ≈ 99.5% ≈ 1.8 days/yr of downtime. This is the single strongest argument against deep synchronous service chains.

4. Networking & Protocols

Pair The distinction
TCP vs UDP TCP = connection, ordered, reliable, retransmits, congestion control, head-of-line blocking. UDP = fire-and-forget datagrams, no ordering or delivery guarantee, no HOL blocking, lowest latency. Voice/video/games/DNS take UDP and handle loss themselves; anything that must not lose bytes takes TCP.
TCP vs QUIC QUIC is reliable-ordered-encrypted transport built on UDP: per-stream ordering (no cross-stream HOL blocking), TLS 1.3 built in (1-RTT or 0-RTT handshake vs TCP+TLS’s 2-3 RTTs), and connection migration across IP changes (Wi-Fi → cellular without dropping). It’s the transport under HTTP/3.
HTTP/1.1 vs HTTP/2 vs HTTP/3 1.1 = one request at a time per connection → browsers open 6 connections per host. 2 = multiplexed streams + header compression (HPACK) + server push over one TCP connection, so a lost packet still stalls all streams (TCP-level HOL). 3 = same multiplexing over QUIC/UDP, so loss on one stream doesn’t stall the others.
Polling vs Long polling vs SSE vs WebSocket vs Webhook Polling = client asks every N sec (simple, wasteful, N-second staleness). Long polling = server holds the request open until data exists (near-real-time over plain HTTP). SSE = one long-lived HTTP response, server→client only, auto-reconnect, text only. WebSocket = full-duplex binary over one upgraded connection. Webhook = server-to-server callback: you give them a URL, they POST to it.
REST vs GraphQL vs gRPC REST = resources + HTTP verbs, cacheable by URL, over/under-fetching is the price. GraphQL = client specifies the exact shape, one round trip for nested data, hard to cache and easy to DoS with a deep query. gRPC = HTTP/2 + protobuf, binary and fast with generated clients and streaming, but not browser-native (needs grpc-web) and not human-debuggable. Default answer: REST at the edge, gRPC between internal services.
Forward vs Reverse proxy Forward proxy sits in front of clients (they know about it; corporate egress, VPN, scraping). Reverse proxy sits in front of servers (clients don’t know; TLS termination, LB, caching, WAF — Nginx, Envoy).
L4 vs L7 load balancing L4 routes on IP:port, can’t read the payload, cheap and protocol-agnostic, one TCP connection passed through (AWS NLB). L7 parses HTTP so it can route on path/header/cookie, retry, and rewrite — two connections, more CPU (ALB, Nginx, Envoy). WebSockets work through L4 naturally; through L7 you need explicit upgrade support.
Load balancer vs API gateway vs Service mesh LB = distribute traffic across identical backends. API gateway = the north-south edge: auth, rate limits, routing, request transformation, API keys. Service mesh = east-west sidecars handling mTLS, retries, and observability between services with no app code.
North-south vs East-west traffic North-south = in/out of the cluster (users → your edge). East-west = service ↔ service inside it. Different tools, different threat models.
Sticky sessions vs Session replication vs Stateless Sticky = LB pins a user to one server (simple; that server dying loses the session, and scaling rebalances badly). Replication = share session state across servers (network chatter). Stateless = state lives in a token or Redis, any server serves any request — the right default.
Anycast vs Unicast vs GeoDNS Unicast = one IP, one location. Anycast = the same IP announced from many locations, BGP routes you to the nearest (how CDNs and public DNS resolvers work; failover is instant and invisible). GeoDNS = resolver returns different IPs based on the client’s location — coarser, and cached by resolvers.
DNS record types A = IPv4. AAAA = IPv6. CNAME = alias to another name (not allowed at the zone apex). ALIAS/ANAME = apex-safe CNAME (provider-specific). MX = mail. TXT = verification/SPF/DKIM. NS = delegation. SRV = service + port. TTL controls how long resolvers cache — lower your TTL before a migration, not during it.
TLS vs SSL vs mTLS SSL is the dead predecessor; everyone says “SSL” and means TLS. TLS = server proves identity via certificate, traffic encrypted. mTLS = both sides present certs — the standard for service-to-service auth inside a mesh.
Encryption in transit vs at rest vs end-to-end In transit = TLS on the wire (your servers still see plaintext). At rest = disk/volume/field encryption (protects stolen disks and misconfigured buckets). End-to-end = only the endpoints hold keys, so the server cannot read the content (Signal, WhatsApp). E2E is what makes server-side search and moderation hard.
CORS vs CSRF vs XSS CORS = a browser rule about which origins may read a cross-origin response (it’s a relaxation mechanism, not a security feature you add). CSRF = attacker makes the victim’s browser send an authenticated request (fix: SameSite cookies + CSRF tokens). XSS = attacker runs JS in your page (fix: escape output + CSP). XSS defeats every CSRF defense, so fix XSS first.
Ingress vs Egress Ingress = inbound. Egress = outbound — and in cloud billing, egress is the expensive direction. Cross-AZ and internet egress costs shape real architectures more than engineers expect.
CDN Push vs Pull Pull (origin pull) = CDN fetches on first miss and caches (easy, first user pays the latency). Push = you upload to the CDN ahead of time (good for large predictable assets like video releases; you manage invalidation and storage).
Edge vs PoP vs Origin Origin = your servers, the source of truth. PoP = a CDN point of presence (a city). Edge = the caching server there that terminates the user’s TLS. Edge compute = running your code at the PoP (Cloudflare Workers, Lambda@Edge).
Idempotent vs Safe HTTP methods Safe = no side effects at all (GET, HEAD, OPTIONS). Idempotent = repeating it has the same effect as once (GET, PUT, DELETE, HEAD). POST is neither — which is exactly why POST needs idempotency keys. PATCH is usually not idempotent ({"$inc": 1} isn’t).
Status codes worth knowing precisely 201 Created (with Location) vs 202 Accepted (queued, not done). 400 (malformed) vs 422 (well-formed, semantically invalid). 401 (not authenticated) vs 403 (authenticated, not allowed). 409 Conflict (version mismatch). 429 (rate limited, send Retry-After). 502 (bad upstream response) vs 503 (temporarily overloaded/down) vs 504 (upstream timed out).

5. Messaging & Streaming

Pair The distinction
Queue vs Topic Queue = point-to-point, one consumer gets each message (work distribution). Topic = pub/sub, every subscriber gets a copy (fan-out). “Should each message be handled once, or by everyone?” picks it.
Message queue vs Event stream Queue = messages are consumed and deleted, the queue is a buffer of pending work (SQS, RabbitMQ). Stream = an append-only log with retention and offsets; consumers read independently and can replay from any point (Kafka, Kinesis). Replay is the differentiator: if you’ll ever need to reprocess history, you need a log.
Push vs Pull consumers Push = broker sends to consumers (low latency, broker must handle slow consumers, easy to overwhelm). Pull = consumer fetches at its own pace (natural backpressure, batching, slight latency cost). Kafka pulls; SQS long-polls (pull that feels like push); webhooks push.
Ack vs Offset vs Visibility timeout Ack = “I processed it, delete it” (SQS/RabbitMQ track per-message state). Offset = a consumer’s position in the log; committing it means “everything before this is done” (Kafka tracks a number, not per-message state — that’s why it scales). Visibility timeout = SQS hides a message while you work; exceed it and it reappears, so someone else processes it too.
Kafka partition vs Consumer group Partition = unit of ordering and parallelism. Consumer group = a set of consumers sharing the work; each partition goes to exactly one consumer in the group. Consequence: consumers > partitions means idle consumers — partition count caps your parallelism. Different groups each get the full stream independently.
At-most-once vs At-least-once vs Exactly-once At-most-once = ack before processing → crash loses the message. At-least-once = ack after processing → crash re-delivers (the default everyone uses). Exactly-once = at-least-once delivery + idempotent processing or transactional offsets.
Delivery semantics vs Processing semantics The broker controls delivery; your consumer controls processing. Kafka’s “exactly-once” is Kafka→Kafka via transactional offset commits. The moment you write to an external system, exactly-once is your dedupe key’s job.
Ordering: global vs per-partition vs per-key Global ordering means one partition means no parallelism — almost never worth it. Per-key ordering (hash the key to a partition) gives you “events for user 42 are ordered” and parallelism. Design your key so ordering is only needed within it.
Fan-out on write vs on read On write (push) = precompute each follower’s feed at post time — fast reads, expensive writes, the celebrity problem. On read (pull) = assemble the feed at request time — cheap writes, slow reads. Real systems go hybrid: push for normal users, pull for accounts with millions of followers.
Choreography vs Orchestration Choreography = services react to each other’s events, no central brain (loose coupling, decentralized, hard to see the whole flow). Orchestration = a coordinator drives each step (visible, debuggable, testable, and now a component that must not go down — Temporal, Step Functions). Use orchestration when the flow has compensation logic you need to reason about.
Event notification vs Event-carried state vs Event sourcing Notification = “order 42 changed” (tiny, consumer calls back for detail → coupling + load). Event-carried state transfer = the event includes the data the consumer needs (no callback, larger events, possible staleness). Event sourcing = the event log is the source of truth, current state is a projection you can rebuild. These three get conflated constantly; naming them separately is an instant credibility signal.
Command vs Event vs Query Command = an imperative request that may be rejected (PlaceOrder), one handler. Event = an immutable statement of fact in the past tense (OrderPlaced), many listeners, cannot be rejected. Query = a read with no side effects.
CQRS vs Event sourcing CQRS = separate the write model from the read model(s). Event sourcing = store the events. They’re independent — you can do CQRS with a plain SQL write DB and a denormalized read table, and that’s usually the right amount of complexity.
DLQ vs Retry queue vs Parking lot Retry queue = transient failures, retried automatically with backoff. DLQ = after N failures, park it here so it stops blocking the pipeline; humans/tools inspect and replay. Parking lot = a DLQ you deliberately drain manually. Without a DLQ, one poison message can stall a partition forever.
Batch vs Micro-batch vs Stream Batch = big bounded chunks, minutes-to-hours, highest throughput per dollar. Micro-batch = tiny batches every few seconds (Spark Structured Streaming) — near-real-time with batch-like efficiency. Stream = per-event, sub-second (Flink, Kafka Streams).
Event time vs Processing time vs Ingestion time Event time = when it happened on the device (correct, but arrives late and out of order). Ingestion time = when your system received it. Processing time = when the operator ran (easy, but results are nondeterministic on replay). Aggregate on event time and use watermarks to decide when a window is closed enough to emit.
Tumbling vs Sliding vs Session windows Tumbling = fixed, non-overlapping (each event in one window: hourly counts). Sliding = fixed size, overlapping stride (5-min count updated every 30s). Session = dynamic, closed by an inactivity gap (user activity bursts).
Lambda vs Kappa architecture Lambda = a batch layer for correctness plus a speed layer for freshness — you maintain the same logic twice. Kappa = one stream pipeline; to “recompute,” replay the log. Kappa is preferred now because replayable logs made the batch layer redundant.

6. Auth, Security & Multi-tenancy

Pair The distinction
Authentication vs Authorization Authn = who are you (401 when it fails). Authz = what may you do (403 when it fails). Different layer, different failure mode; a gateway can do authn but authz usually needs domain context, so it belongs in the service.
JWT vs Opaque token vs Session JWT = self-contained signed claims, verified with a public key and no network call — the trade is you cannot revoke it before expiry. Opaque token = a random string the auth server must introspect (revocable, adds a hop). Session = server-side state keyed by a cookie (easy to revoke, needs a shared store). Standard production answer: short-lived JWT access token + long-lived revocable refresh token.
Access vs Refresh vs ID token Access token = sent to APIs, short TTL (5-15 min), carries scopes. Refresh token = long-lived, stored securely, only ever sent to the auth server to mint new access tokens (and can be rotated + revoked). ID token = OIDC only, describes who the user is, for your client — never send it to an API as authorization.
OAuth 2.0 vs OIDC vs SAML OAuth 2.0 = delegated authorization (“this app may read your Drive”). It is not a login protocol. OIDC = a thin identity layer on top of OAuth that adds the ID token — this is “Sign in with Google.” SAML = the XML-based enterprise SSO predecessor, still everywhere in B2B.
RBAC vs ABAC vs ReBAC vs ACL RBAC = permissions via roles (simple, explodes into role sprawl). ABAC = policy over attributes of user/resource/context (“same department AND business hours”). ReBAC = permissions derived from a relationship graph (Google Docs sharing, Zanzibar). ACL = per-object list of who can do what.
Hashing vs Encryption vs Encoding Encoding (base64) = reversible by anyone, zero security, it’s a format. Encryption = reversible with a key. Hashing = one-way. For passwords use a slow hash designed for it (bcrypt/argon2/scrypt), never SHA-256 — speed is the vulnerability.
Symmetric vs Asymmetric Symmetric (AES) = one shared key, fast, key distribution is the hard part. Asymmetric (RSA/ECDSA) = public/private pair, slow, solves distribution. TLS uses asymmetric to agree on a symmetric key, then switches — best of both.
Salt vs Pepper vs Nonce vs IV Salt = per-password random value, stored alongside, defeats rainbow tables. Pepper = a secret constant kept outside the DB, so a DB leak alone isn’t enough. Nonce/IV = a number used once per encryption, so identical plaintexts don’t produce identical ciphertext — reusing one is a classic catastrophic bug.
Signature vs MAC vs HMAC MAC/HMAC = shared secret, so anyone who can verify can also forge — no non-repudiation. Signature = private key signs, public key verifies, so only the holder could have produced it. JWT HS256 is HMAC (shared secret); RS256 is a signature (services verify with a public key and cannot mint tokens) — prefer RS256 for multi-service systems.
Rate limit vs Quota Rate limit = requests per short window, protects capacity (100/min, 429). Quota = total allowance over a billing period, protects revenue and cost (1M calls/month).
Silo vs Pool vs Bridge multi-tenancy Silo = a dedicated stack per tenant (strongest isolation, worst cost/ops). Pool = shared infra with a tenant_id everywhere (cheapest, one missing WHERE clause is a data breach — enforce with row-level security, not discipline). Bridge = shared compute, isolated storage per tenant. Noisy-neighbour control is the recurring pool problem.

7. Architecture, Deploys & Algorithms

Pair The distinction
Monolith vs Modular monolith vs Microservices vs SOA Monolith = one deployable, shared DB, easy until the team grows. Modular monolith = one deployable, enforced internal module boundaries and no cross-module table access — the correct default, and the cheapest path to microservices later. Microservices = independently deployable, own their data, network-coupled. SOA = the enterprise predecessor with a central ESB.
Strangler fig vs Big-bang rewrite Strangler = put a proxy in front of the legacy system and move routes to the new one incrementally, both running (safe, slow, reversible). Big-bang = rewrite and cut over (fast in theory, historically catastrophic). Always propose the strangler.
Blue-green vs Canary vs Rolling vs Shadow Blue-green = two full environments, flip traffic at once (instant rollback, 2× cost, DB migrations are the hard part). Canary = route 1% → 5% → 50% while watching metrics (catches real-traffic bugs, needs good observability). Rolling = replace instances batch by batch (no extra cost, both versions live so N and N+1 must be compatible). Shadow/dark launch = mirror real traffic to the new version and discard responses (zero user risk, great for load-testing; careful with side effects).
Deploy vs Release Deploy = the code is on the servers. Release = users can see it. Feature flags decouple them — which is what makes trunk-based development and safe Friday deploys possible.
Stateless vs Stateful Stateless = any instance can serve any request, scaling and restarts are trivial. Stateful = the instance holds data or a session, so scaling means data movement and restarts mean failover. Push state to the edges (DB, cache, token) and keep the middle tier stateless.
Liveness vs Readiness vs Startup probe Liveness fail → restart the container (use it only for “wedged beyond recovery”). Readiness fail → remove from the LB but leave it running (use for warmup, or a dependency being down). Startup probe = don’t judge me yet, I’m booting. Pointing liveness at a shared dependency causes fleet-wide restart storms.
Horizontal vs Vertical autoscaling HPA = more replicas (stateless services; needs headroom for scale-up latency). VPA = more CPU/RAM per pod (usually needs a restart; right for stateful things you can’t shard). Scale on the metric closest to user pain — queue depth or p99, not CPU.
Sidecar vs Ambassador vs Adapter Sidecar = a helper container in the same pod sharing lifecycle/network (log shipper, Envoy). Ambassador = a sidecar that proxies outbound calls (so the app just talks to localhost). Adapter = normalizes the app’s output for an external system (metrics format translation).
Consistent hashing vs Mod hashing vs Rendezvous hashing hash % N remaps almost every key when N changes. Consistent hashing on a ring remaps ~K/N keys; virtual nodes fix the uneven-load problem. Rendezvous (HRW) hashing = for each key compute a score per node and pick the highest — same minimal-disruption property, simpler code, no ring or vnodes to manage.
Cache-aside vs Read-through vs Write-through vs Write-behind vs Refresh-ahead Cache-aside = app manages both (most common, cache can be stale/missing and that’s fine). Read-through = the cache library fetches on miss. Write-through = write cache + DB synchronously (consistent, slower writes). Write-behind = write cache, flush async (fastest, can lose data if the cache dies). Refresh-ahead = proactively refresh hot keys before expiry (kills stampedes on known-hot keys).
TTL vs LRU vs LFU vs ARC TTL bounds staleness. LRU/LFU bound size. LRU is recency-based and gets wrecked by a big scan flushing your hot set; LFU is frequency-based and resists that but adapts slowly to shifts; ARC/W-TinyLFU balance both. You almost always want a TTL and an eviction policy.
Bloom vs Cuckoo filter vs HyperLogLog vs Count-Min Sketch Bloom = “is x present?” with false positives, no false negatives, no deletes. Cuckoo filter = same job, supports deletes, better space at low error rates. HyperLogLog = approximate distinct count in ~12KB for billions of items (unique visitors). Count-Min Sketch = approximate frequency per item (top-K, heavy hitters). Naming the right sketch for the right question is a strong signal.
Trie vs Inverted index Trie = prefix tree, answers “words starting with ‘sys’” — autocomplete. Inverted index = term → list of document IDs, answers “documents containing ‘system’ and ‘design’” — full-text search (Elasticsearch/Lucene). Autocomplete is a trie problem; search is an inverted-index problem.
Geohash vs Quadtree vs H3 vs R-tree Geohash = interleave lat/long bits into a sortable string; prefix = bounding box, so any KV store can do proximity — but boxes near the poles/edges distort and neighbours can differ at the first char. Quadtree = recursive subdivision, adapts to density. H3 = hexagonal grid, uniform neighbour distance (Uber). R-tree = bounding-box tree, the classic in PostGIS.
Idempotency key vs Request ID vs Correlation ID vs Trace ID Idempotency key = client-generated, used for dedupe on retry, must be stable across retries of the same intent. Request ID = unique per attempt, for logs. Correlation/Trace ID = propagated across every service in one user journey so you can stitch the logs together. Different jobs — don’t reuse one for all three.

8. The 20 highest-yield rapid-fire answers

If you only memorize one section, memorize this one. These are the ones interviewers actually ask.

Question Your 15-second answer
Partition vs shard? Sharding is partitioning across separate machines. Partitioning can be one server (Postgres monthly partitions). All sharding is partitioning; the reverse isn’t true.
Replication vs sharding? Replication copies the same data for read scale + availability; sharding splits different data for write scale + capacity. Production uses both.
Latency vs throughput? Time per op vs ops per second. Batching raises throughput and hurts latency. Related through Little’s Law: concurrency = rate × latency.
Why p99 not average? One 30s timeout disappears into an average of 5ms requests. At 10K rps, p99 is 100 users/second having a bad experience. And you can’t average percentiles across hosts.
Horizontal vs vertical scaling? Vertical = bigger box, simplest, hard ceiling, restart to resize. Horizontal = more boxes, unlimited-ish, now you own distributed state. Scale vertically until it hurts, then horizontally.
Strong vs eventual consistency? Strong = every read sees the latest write, costs a coordination round trip. Eventual = replicas converge in ms-to-seconds, cheaper and available under partition. Pick per component, not per system.
Linearizability vs serializability? Recency on a single object vs a serial-equivalent order over transactions. Both = strict serializability (Spanner).
ACID’s C vs CAP’s C? ACID-C = invariants hold after a transaction. CAP-C = replicas agree on the latest value. Same letter, unrelated properties.
At-least-once vs exactly-once? Exactly-once delivery is impossible; exactly-once processing = at-least-once + idempotent consumer or dedupe key.
Kafka vs SQS? Kafka = replayable ordered log, retention, millions/sec, consumer groups. SQS = managed work queue, message deleted on ack, no replay. Need replay or ordering → Kafka; just “do this later” → SQS.
Queue vs topic? Queue = one consumer handles each message. Topic = every subscriber gets a copy.
L4 vs L7? L4 routes on IP:port, blind to content, cheap. L7 reads HTTP so it can route on path/header, retry, and terminate TLS.
Forward vs reverse proxy? Forward sits in front of clients (they configure it). Reverse sits in front of servers (clients don’t know it exists).
API gateway vs load balancer? LB distributes to identical backends. Gateway adds auth, rate limiting, routing, and transformation at the edge.
TCP vs UDP? Reliable ordered stream with congestion control vs unreliable unordered datagrams with no head-of-line blocking.
WebSocket vs SSE? WebSocket = bidirectional binary, custom protocol, proxies need config. SSE = server→client only, plain HTTP, auto-reconnect, dead simple. Only need server pushes? SSE.
Authentication vs authorization? Who you are (401) vs what you may do (403).
JWT vs session? JWT = stateless, verified locally, hard to revoke. Session = server state, trivially revocable, needs a shared store. Use short-lived JWT + revocable refresh token.
Optimistic vs pessimistic locking? Optimistic = version check on write, retry on conflict (low contention). Pessimistic = lock up front (high contention or expensive retries).
2PC vs Saga? 2PC = atomic, blocking, holds locks, coordinator is a SPOF. Saga = local transactions + compensations, no locks, intermediate states are visible. Microservices use sagas.
RPO vs RTO? How much data you can lose vs how long you can be down.
Backpressure vs load shedding? Slow the producer down (keep the work) vs drop requests (protect the system).
SLO vs SLA? Internal target vs external contract with penalties. The SLA is always looser than the SLO.

How to use this page

  1. Skim all of it once — you’ll be surprised how many you half-knew.
  2. Cover the right column and self-test on section 8 until every answer is automatic.
  3. When you get one wrong, open the matching deep dive: the distinction is a symptom, the concept page is the cure.
  4. In the interview, define the term the first time you use it in one clause: “we’ll shard by user ID — partitioning across separate instances, so writes scale.” You’ve now answered the follow-up before it was asked.

⚠️ Don’t do this: reciting distinctions unprompted as a vocabulary flex. These are 15-second answers to direct questions, or one-clause asides inside your design. Nobody wants a lecture on PACELC while you’re supposed to be drawing boxes.


For Read
Sharding strategies, hot partitions, resharding Database Sharding
Isolation levels and the anomalies they permit Transactions & Isolation Levels
Percentiles, Little’s Law, SLOs, capacity math Performance Metrics
TCP/HTTP versions, DNS, TLS handshakes Networking Basics
Canary, blue-green, RPO/RTO, failover drills Deployment & Reliability
Snowflake, UUIDv7, ULID, ticket servers Unique ID Generation
Metrics vs logs vs traces, RED/USE, cardinality Observability
CP vs AP, PACELC CAP Theorem
Quorums, replication topologies Database Replication

← Back to Fundamentals Next: Transactions & Isolation Levels →

Free system design + DSA prep. If it helped you crack an interview, consider supporting.