The Model
the entire API:
GET key → value (or nothing)
PUT key, value → store it
DELETE key → remove it
no queries by value. no joins. no secondary lookups.
EVERYTHING must be reachable through its key.
users:912 → {"name": "Sarah", ...}
sess:a83f → {userId: 912, exp: ...}
rate:u:912 → 47
What Simplicity Buys
| Property | Mechanism |
|---|---|
| Speed | Hash/B-tree lookup = O(1)-ish; no planner |
| Scale | Key space shards trivially — no cross-key relationships |
| Predictability | Latency doesn’t depend on query shape |
| Availability designs | Dynamo-style replication without coordination |
the constraint IS the feature:
knowing all access goes through keys lets implementations
make extreme promises (sub-ms reads, linear scaling)
that relational generalism cannot.
The Design Questions Every KV Answers
1. WHAT IS A VALUE? bytes (Memcached) vs structures (Redis)
2. WHERE DOES IT LIVE? memory only / disk-backed / hybrid
3. CONSISTENCY? single-node strong / replicated eventual /
quorum tunable (DynamoDB W+R>N)
4. HOW DOES IT SCALE? client-side sharding / consistent hashing /
managed partitioning
5. EXPIRY MODEL? TTL support, eviction policies
The Spectrum of Systems
Redis in-memory, rich structures, persistence options,
single-threaded core (~100k ops/s/node), clustering
Memcached pure multi-threaded RAM cache; strings; dead simple
DynamoDB managed, disk-based, quorum consistency,
effectively unlimited scale, per-request pricing
Cassandra (wide-column but used KV-style) massive writes
choosing:
cache/session hot path → Redis
simple durable at scale → DynamoDB
enormous write volumes → Cassandra-family
Access-Pattern Discipline
KV stores punish relational thinking:
✗ "find all sessions for user X"
if sessions keyed by session_id → impossible! full scan.
✓ design keys from QUERIES backwards:
need user's sessions? → key them user:{id}:sess:{sid}
or maintain an index set: SADD user:{id}:sessions sid
key design = schema design here. sketch access patterns FIRST,
then derive keys — never the reverse.
When KV Fits
✓ caching layers (the canonical use)
✓ sessions/tokens with TTLs
✓ counters/rate limiters (atomic ops)
✓ feature flags/config
✓ shopping carts (hash-per-cart)
✗ anything needing queries-by-content
✗ relational integrity requirements
✗ ad-hoc analytics
if you're writing "scan all keys matching..." you've
left KV territory — pick another family.
Interview Framing
“Where does key-value fit in your design?” scored answers show key-design-from-access-patterns (“sessions queried by id → sess:{sid}; also need user’s active list → index set”), TTL discipline, and engine choice rationale (Redis for hot path speed vs DynamoDB for durable scale). The anti-pattern callout — discovering mid-design that you need secondary queries — demonstrates the modeling lesson learned.
Premium Content
Unlock Key-Value Stores and all premium lessons with a subscription.
All premium lessons
Ad-free experience
Priority support
From ₹199.99/year — See plans