001Notes
System Design Interview Notes
On this page149
Deep-answer interview notes for system design questions: APIs, caches, Kafka, consistency, disaster recovery, and Spanner.
Article details
- Status
- Building Publicly
- Subcategory
- System Design
- Last reviewed
- 26 Aug 2026
- Prerequisites
- HTTP and networking basics · Databases · Concurrency fundamentals
149 sections
SD.1 — All types of API
REST
GET /users/123 → 200 + user JSON
POST /users → 201 + new user
PUT /users/123 → 200 (full replace)
PATCH /users/123 → 200 (partial)
DELETE /users/123 → 204
GraphQL
query {
user(id: 123) {
name
posts(last: 5) { title comments(last: 2) { author { name } } }
}
}
gRPC
service UserService {
rpc GetUser(GetUserRequest) returns (User);
rpc StreamUsers(stream UserFilter) returns (stream User);
}
WebSocket
client → server: HTTP Upgrade: websocket
server → client: 101 Switching Protocols
[binary or text frames in either direction]
Server-Sent Events (SSE)
HTTP/1.1 200 OK
Content-Type: text/event-stream
data: hello
event: tick
data: {"time": 123}
Polling / long polling
Webhooks
SOAP
<soap:Envelope>
<soap:Body><GetUser><Id>123</Id></GetUser></soap:Body>
</soap:Envelope>
JSON-RPC / XML-RPC
{"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}
MQTT
Comparison table
| API style | Transport | Direction | Shape | Use case |
|---|---|---|---|---|
| REST | HTTP/1.1 or 2 | request/response | client-defined URL, server-defined body | public API, CRUD |
| GraphQL | HTTP | request/response (+ WS subscriptions) | client-defined query | client-driven aggregation |
| gRPC | HTTP/2 | uni or bi-streaming | proto-defined | internal microservices |
| WebSocket | TCP after HTTP upgrade | full duplex | freeform | chat, games, trading |
| SSE | HTTP/1.1 or 2 | server → client | freeform text events | dashboards, notifications |
| Webhook | HTTP | server → server | provider-defined | event integration |
| SOAP | HTTP/other | request/response | strict XML | enterprise legacy |
| MQTT | TCP | pub/sub | tiny binary | IoT |
SD.2 — API versioning
Why version
Strategies
GET /v1/users/123
GET /v2/users/123
GET /users/123
Accept: application/vnd.acme.v2+json
GET /users/123?api_version=2
GET https://v2.api.acme.com/users/123
Semantic versioning
Compatibility patterns
gRPC specifics
Deprecation policy
Real-world example: Stripe
SD.3 — MongoDB vs others — read/write performance
What MongoDB is
Write performance
| DB | Typical writes/sec (single shard, durable) | Why |
|---|---|---|
| Postgres | 5K–30K | row-level locks, WAL, MVCC |
| MySQL (InnoDB) | 5K–30K | similar to PG |
| MongoDB | 5K–20K | document-level locking |
| Cassandra | 50K–200K | log-structured, no read-before-write on insert |
| DynamoDB | 10K–40K per partition | provisioned, request-routed |
| ScyllaDB | 100K–500K | C++ rewrite of Cassandra, shard-per-core |
Read performance
| DB | Read characteristics |
|---|---|
| Postgres | full SQL, complex joins fast with planner, MVCC reads |
| Mongo | denormalized docs avoid joins, $lookup is slow |
| Cassandra | single-partition reads fast, cross-partition is fan-out |
| Redis | in-memory, sub-ms |
| DynamoDB | partition+sort key reads fast; scan is slow |
| Elasticsearch | full-text search, aggregations on terms |
Why Mongo wins / loses
Sharding
Replica sets
Disk layout
SD.4 — Caches
What caching is for
Cache tiers in a typical web stack
| Tier | Latency | Capacity | What |
|---|---|---|---|
| CPU L1 | 1 ns | 32 KB | per-core, code+data |
| CPU L2 | 4 ns | 256 KB–1 MB | per-core |
| CPU L3 | 12 ns | 30 MB | shared per socket |
| OS page cache | 50 ns | RAM | file contents |
| App in-process | 100 ns | RAM | object cache |
| Local Redis/memcached | 100 μs | per-node RAM | cluster cache |
| Distributed cache (cluster) | 500 μs | aggregate RAM | hot data |
| Database | 1–10 ms | TB | source of truth |
| CDN | 10–50 ms (first hop) | global | static assets, API responses |
| Browser | 0 (local disk) | per-user | per-user assets |
Local vs global cache
Write strategies
| Strategy | Behavior | Trade |
|---|---|---|
| Write-through | write goes to cache AND DB synchronously | safe; slow writes; cache always coherent |
| Write-back | write to cache, flush later | fast writes; data loss on cache failure |
| Write-around | write goes to DB only; cache populated on read | safe for write-heavy data; first read slow |
| Read-through | cache miss fetches from DB and populates | cleanest separation |
| Cache-aside | app manages cache miss + repopulate | most flexible; most bug-prone |
Eviction policies
Indexing inside the cache
Hot data
Cache stampede / dogpile
Negative caching
SET user:9999 "MISSING" EX 60
Cache invalidation patterns
Distributed cache consistency
T1 reads X (miss), reads DB → 5
T2 writes X = 6 to DB, invalidates cache (no-op since not in cache yet)
T1 inserts 5 into cache ← stale
CDN
SD.5 — Kafka deep dive
What Kafka is
Topology
Producer ──┐ ┌── Consumer (group A, instance 1)
Producer ──┤ ├── Consumer (group A, instance 2)
│ │
▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Broker1 │ │ Broker2 │ │ Broker3 │
└─────────┘ └─────────┘ └─────────┘
▲ ▲ ▲
└─── controller (KRaft or ZK)
Topics and partitions
topic "orders":
partition 0: [r0, r1, r2, r3, ...]
partition 1: [s0, s1, s2, ...]
partition 2: [t0, t1, t2, ...]
Partition assignment by key
producer.send("orders", key="user_123", value=order_json)
Brokers
Replication
acks=0 → fire-and-forget; producer doesn't wait. Data loss on failure.
acks=1 → leader writes locally and ACKs. Leader crash before replication = data loss.
acks=all → leader waits for all ISR to ACK. Safest. min.insync.replicas=2 means at least 2 ISR must exist for write to succeed.
Log layout
/var/kafka/orders-0/
00000000000000000000.log # records 0..N
00000000000000000000.index # offset → byte
00000000000000000000.timeindex # time → offset
00000000000123456789.log # records N..M
...
Producer guarantees
Consumer groups
group "billing":
instance A → partitions 0, 1
instance B → partitions 2, 3
Offsets
Why Kafka is fast
Log compaction
key=user:1, value={name: "Alice", balance: 100} ← discarded after newer one
key=user:1, value={name: "Alice", balance: 150} ← kept (latest for key)
key=user:2, value=...
Coordinator (KRaft / ZooKeeper)
Common configuration pitfalls
Mirror Maker / replication across clusters
SD.6 — Redis vs Memcached vs others
Redis
SET k v EX 60
LPUSH q x; RPOP q
ZADD scores 100 alice; ZRANGE scores 0 -1 WITHSCORES
HSET user:1 name alice age 30
XADD events * type click user 123
Memcached
Decision
| Want | Use |
|---|---|
| Just a cache, raw KV, multi-core | Memcached |
| Data structures (queues, sets, sorted sets, streams) | Redis |
| Persistence | Redis |
| Pub/sub or streams | Redis |
| Rate limiting, locks, atomic ops | Redis (Lua, INCR, SETNX, Redlock) |
| Geographic / vector / search | Redis with modules |
Other in-memory systems
Use case examples
SD.7 — Zookeeper
What it is
ZAB protocol
Guarantees
Znodes
/services/db/leader-0000000042 (ephemeral sequential)
/services/db/leader-0000000043
Watches
Use cases
Limits
Alternatives
When NOT to use
SD.8 — SQS vs SNS vs RabbitMQ vs Kafka
SQS (Amazon Simple Queue Service)
SNS (Amazon Simple Notification Service)
RabbitMQ
Kafka
Comparison
| Aspect | SQS | SNS | RabbitMQ | Kafka |
|---|---|---|---|---|
| Model | queue | pub/sub | broker (exchange→queue) | log |
| Pull/push | pull | push | both | pull |
| Ordering | FIFO queue only | FIFO topic only | per queue | per partition |
| Throughput | unlimited (std) | unlimited | 10K–100K msg/s | millions msg/s |
| Latency | ~10ms | ~10ms | ~1ms | ~5ms |
| Replay | no | no | no (msg gone after ack) | yes (retention) |
| Persistent log | no | no | optional | yes |
| Routing logic | basic | topic filters | rich exchanges | partition by key |
| Ops burden | zero (managed) | zero | medium | high |
| Per-message ack | yes | n/a | yes | offset-based |
| Priorities | no | no | yes | no |
Decision tree
SD.9 — AWS-based Semantic DB (vector search)
What semantic search is
AWS options
SELECT id, content FROM docs
WHERE tenant_id = 42
ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector
LIMIT 10;
Embedding pipeline
Document → Chunker → Embedding model → Vector + metadata → Vector DB
Query → Embedding model → ANN query → Top K → (rerank) → LLM context
Tuning
Hybrid retrieval
score(doc) = 1/(k + rank_bm25) + 1/(k + rank_vector)
Reranking
SD.10 — Collaborative service scaling (Sheets, Zoom)
Collaborative document (Google Sheets, Figma)
Operational Transformation (OT)
Server state: "abc"
User A inserts 'X' at position 1: "aXbc"
User B inserts 'Y' at position 2 (in original): "abYc"
Server transforms B against A: position 2 → 3 (shifted by A's insert): "aXbYc"
CRDT (Conflict-free Replicated Data Types)
Architecture pattern (OT/CRDT-based)
Client ─WS─► Edge ─► Doc Service (shard by doc_id)
│
├── In-memory document state
├── Op log (Kafka or DB append-only)
└── Snapshots (S3 every N ops)
Real-time media (Zoom, Google Meet)
Topologies
Simulcast / SVC
Scaling SFUs
Transport
Latency
Recording / VOD
Live streaming layer
SD.11 — WebRTC, RTSP, RTP, WebSocket, SSE, polling, QUIC, UDP
RTP (Real-time Transport Protocol)
RTSP (Real Time Streaming Protocol)
WebRTC
WebSocket
GET /chat HTTP/1.1
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: ...
SSE (Server-Sent Events)
const es = new EventSource('/events');
es.onmessage = (e) => console.log(e.data);
Polling
Client: GET /messages?since=1234
Server: 200 OK [messages]
sleep 5s
repeat
Long polling
QUIC
UDP congestion control
SD.12 — Inter-region consistency
The fundamental problem
Replication patterns
Single-region with async cross-region replicas
Multi-master (active-active) with last-writer-wins
Multi-master with CRDT merge
Multi-region with strong consistency
Reading
Cross-region conflict handling
Read-your-writes guarantees
Region failure / failover
SD.13 — Disaster recovery per system
RTO and RPO
Tiers
| Tier | RTO | RPO | Approach |
|---|---|---|---|
| Backup/restore | hours-days | hours | nightly snapshots; restore on DR site |
| Pilot light | hours | minutes | minimal infra always running; scale up on failover |
| Warm standby | minutes | seconds | scaled-down full stack always running |
| Multi-site active-active | seconds | zero (or near) | live traffic across regions |
Per-system patterns
Postgres / MySQL
Kafka
Redis
MongoDB
Cassandra/Scylla
Object storage (S3)
DNS / load balancing
Application servers
Testing DR
Backups vs DR
SD.14 — Eventual consistency
Definition
CAP theorem reminder
Anti-entropy mechanisms
Read repair
Hinted handoff
Merkle trees
Gossip
Conflict resolution
Tunable consistency
Read-your-writes / monotonic reads / session guarantees
Examples of EC in the wild
SD.15 — Google Spanner
The big idea
TrueTime
Commit Wait
Architecture
Key features
Performance
Comparison with CockroachDB
Comparison with FaunaDB
Comparison with regular RDBMS
When to use Spanner
When NOT to use Spanner
Counterexample: treating TrueTime as a perfect clock
Primary references