Requirements & scope
Problem Statement & Requirements
Functional Requirements
put(key, value)— store a key-value pairget(key)→ value — retrieve the value for a given keydelete(key)— remove a key-value pair- Support variable-size values (1 byte to 1 MB)
- Keys are strings (up to 256 bytes)
- Automatic data expiration (TTL support)
Non-Functional Requirements
- High availability — always writable, even during network partitions (AP system)
- Low latency — single-digit millisecond reads and writes (p99 < 10 ms)
- Scalability — horizontally scale to petabytes across thousands of nodes
- Durability — no data loss once acknowledged
- Tunable consistency — allow clients to choose between strong and eventual consistency per request
- Fault tolerance — handle node failures, network partitions, and datacenter outages
Out of Scope
- Range queries / secondary indexes (that's a full database)
- Transactions across multiple keys
- Complex data types (lists, sets, sorted sets — that's Redis)
- SQL query interface
Scale estimations
Scale Estimations
Traffic & Storage
| Metric | Value |
|---|---|
| Total key-value pairs | 10 billion |
| Average key size | 64 bytes |
| Average value size | 10 KB |
| Total data size | 10B × ~10 KB = ~100 TB |
| Replication factor | 3 |
| Total storage with replication | ~300 TB |
| Reads / second | 500K RPS |
| Writes / second | 100K RPS |
| Read:Write ratio | 5:1 |
Node Sizing
| Metric | Value |
|---|---|
| Storage per node | 2 TB SSD |
| Nodes needed (data) | 300 TB / 2 TB = 150 nodes |
| RAM per node | 64 GB |
| Total cluster RAM | 150 × 64 GB = 9.6 TB |
| Hot data in memory | ~10% of data = 10 TB → distributed across nodes |
Network
| Metric | Value |
|---|---|
| Read bandwidth | 500K × 10 KB = ~5 GB/s |
| Write bandwidth | 100K × 10 KB = ~1 GB/s |
| Per-node read bandwidth | 5 GB/s / 150 = ~33 MB/s |
| Replication bandwidth | 1 GB/s × 2 (replicas) = ~2 GB/s |
Layered architecture
High-Level Architecture
High-Level ArchitectureExcalidraw diagram · editable shapes · reveal step by stepExplore
API & contracts
Data Model & API
Wire Protocol
Wire ProtocolExcalidraw diagram · editable shapes · reveal step by stepExplore
Internal Data Format (On Disk)
Internal Data Format (On Disk)Excalidraw diagram · editable shapes · reveal step by stepExplore
Data model
Storage Engine
LSM-Tree (Log-Structured Merge Tree) — Write-Optimized
LSM-Tree (Log-Structured Merge Tree) — Write-OptimizedExcalidraw diagram · editable shapes · reveal step by stepExplore
Bloom Filters — Avoiding Unnecessary Disk Reads
Bloom Filters — Avoiding Unnecessary Disk ReadsExcalidraw diagram · editable shapes · reveal step by stepExplore
B-Tree vs LSM-Tree Tradeoff
| Aspect | LSM-Tree | B-Tree |
|---|---|---|
| Write throughput | ✅ Excellent (sequential I/O) | ❌ Random I/O for each write |
| Read latency | ❌ May check multiple levels | ✅ O(log N) single lookup |
| Space amplification | ❌ Temporary duplicates during compaction | ✅ In-place updates |
| Write amplification | ❌ Data written multiple times (compaction) | ✅ Written once (usually) |
| Range queries | ✅ Data sorted within SSTables | ✅ Natural ordering |
| Best for | Write-heavy KV stores (our use case) | Read-heavy databases |
Our choice: LSM-Tree — write-heavy workload, sequential disk I/O, good for SSDs.
Core design decisions
CAP Theorem & Design Philosophy
CAP Theorem & Design PhilosophyExcalidraw diagram · editable shapes · reveal step by stepExplore
Our choice: AP with tunable consistency
- Default to availability + partition tolerance
- Allow clients to request stronger consistency when needed (quorum reads)
- This is the Dynamo model — write always succeeds, conflicts resolved on read
Core Component: Consistent Hashing
The Problem with Naive Hashing
The Problem with Naive HashingExcalidraw diagram · editable shapes · reveal step by stepExplore
Consistent Hashing Solution
Consistent Hashing SolutionExcalidraw diagram · editable shapes · reveal step by stepExplore
Virtual Nodes (vnodes) — Solving Uneven Distribution
Virtual Nodes (vnodes) — Solving Uneven DistributionExcalidraw diagram · editable shapes · reveal step by stepExplore
How Many Virtual Nodes?
| Nodes in Cluster | vnodes per Node | Total Ring Positions | Load Std Dev |
|---|---|---|---|
| 10 | 100 | 1,000 | ~5% |
| 50 | 150 | 7,500 | ~2% |
| 150 | 200 | 30,000 | ~1% |
Tradeoff: More vnodes = better distribution but more metadata to maintain and transfer during rebalancing.
Tunable Consistency (Quorum)
The N, W, R Parameters
The N, W, R ParametersExcalidraw diagram · editable shapes · reveal step by stepExplore
Common Configurations
Common ConfigurationsExcalidraw diagram · editable shapes · reveal step by stepExplore
Sloppy Quorum & Hinted Handoff
Sloppy Quorum & Hinted HandoffExcalidraw diagram · editable shapes · reveal step by stepExplore
Request flows
Detailed Flow Diagrams
Write Flow
Write FlowExcalidraw diagram · editable shapes · reveal step by stepExplore
Read Flow
Read FlowExcalidraw diagram · editable shapes · reveal step by stepExplore
Read Repair
Read RepairExcalidraw diagram · editable shapes · reveal step by stepExplore
Performance & caching
Compaction Strategies
Compaction StrategiesExcalidraw diagram · editable shapes · reveal step by stepExplore
Advanced design
Data Partitioning & Replication
Partition Assignment
Partition AssignmentExcalidraw diagram · editable shapes · reveal step by stepExplore
Replication Strategy
Replication StrategyExcalidraw diagram · editable shapes · reveal step by stepExplore
Conflict Resolution
When multiple replicas accept concurrent writes to the same key (during a partition or with W < N), conflicts arise.
Vector Clocks
Vector ClocksExcalidraw diagram · editable shapes · reveal step by stepExplore
Conflict Resolution Strategies
Conflict Resolution StrategiesExcalidraw diagram · editable shapes · reveal step by stepExplore
Anti-Entropy: Merkle Trees
For replicas that haven't served reads recently, stale data can go undetected. Merkle trees solve this.
Anti-Entropy: Merkle TreesExcalidraw diagram · editable shapes · reveal step by stepExplore
Edge cases
Workshop note · added for the website’s common reading format
Walk through three failure moments in Key-Value Store: a request times out before its result is known; a dependency becomes slow rather than unavailable; and a process restarts after committing state but before acknowledging it.
For each case, name the authoritative record, define a safe retry, cap resource usage, and describe what the caller sees. Anti-entropy should help detect and contain the problem: Compare replica ranges and repair divergence in the background.
Tradeoffs
Tradeoffs & Design Decisions Summary
| Decision | Option A | Option B | Chosen | Why |
|---|---|---|---|---|
| CAP | CP (strong consistency) | AP (high availability) | AP (tunable) | Write availability is critical; clients can choose consistency level |
| Partitioning | Range-based | Consistent hashing | Consistent hashing + vnodes | Even distribution, minimal redistribution on scale |
| Replication | Leader-based | Leaderless (quorum) | Leaderless | No single point of failure, tunable W/R |
| Conflict resolution | LWW (simple) | Vector clocks (accurate) | Vector clocks | Preserves concurrent writes, no silent data loss |
| Storage engine | B-Tree | LSM-Tree | LSM-Tree | Write-heavy workload, sequential I/O |
| Failure detection | Heartbeat (centralized) | Gossip (decentralized) | Gossip | No single failure detector, scales to thousands of nodes |
| Anti-entropy | Full sync | Merkle tree diff | Merkle trees | O(log N) comparisons, minimal data transfer |
| Compaction | Size-tiered | Leveled | Leveled (default) | Better read performance, lower space amplification |
| Consistency model | Fixed (always strong) | Tunable (N/W/R) | Tunable | Different use cases need different guarantees |
| Membership | Static config | Dynamic (gossip) | Dynamic gossip | Nodes join/leave without manual config changes |
Reliability & fault tolerance
Failure Detection: Gossip Protocol
Failure Detection: Gossip ProtocolExcalidraw diagram · editable shapes · reveal step by stepExplore
Node Join / Leave / Failure Handling
Adding a New Node
Adding a New NodeExcalidraw diagram · editable shapes · reveal step by stepExplore
Handling Node Failure
Handling Node FailureExcalidraw diagram · editable shapes · reveal step by stepExplore
Production architecture
Production Architecture
Production ArchitectureExcalidraw diagram · editable shapes · reveal step by stepExplore
Further exploration
Comparison with Real Systems
Comparison with Real SystemsExcalidraw diagram · editable shapes · reveal step by stepExplore
Interview playbook
Interview Tips
Start with CAP — "Before diving into the design, let me clarify the consistency model. For a KV store, we usually want AP with tunable consistency." This frames the entire design.
Consistent hashing is the centerpiece — Draw the ring, explain vnodes, show why naive modulo hashing fails. This is the core algorithmic insight.
Walk through a write + read flow — Show how data flows through WAL → MemTable → SSTable, and how quorum reads work. This demonstrates you understand the full data path.
Discuss vector clocks carefully — Use a concrete example with two concurrent writes. Show how conflicts are detected and how the client resolves them.
Mention Merkle trees for anti-entropy — This shows you think about long-term consistency, not just the happy path. "How does a replica that was down for 2 hours catch up?"
Don't forget the storage engine — LSM-Tree with bloom filters is the standard answer. Explain write amplification as a tradeoff.
Gossip protocol for membership — Shows you understand decentralized failure detection. Mention the convergence time (O(log N) rounds).
Name real systems — "This is essentially the Dynamo paper architecture" or "Cassandra uses a similar approach but with LWW instead of vector clocks." Shows you've read the literature.
Tombstones for deletes — A subtle but important point. "You can't just delete from one replica — the other replicas will think the key still exists and resurrect it."