Key-value: the simplest storage contract
Key → value (opaque blob). No secondary query model unless added (DynamoDB GSIs, Redis modules). Optimized for O(1) point lookups at massive scale.
Foundation of caching layers, session stores, feature flags, and coordination primitives.
Redis: in-memory with optional persistence
Data structures (strings, hashes, lists, sets, sorted sets) live in RAM for microsecond latency.
| Persistence | Mechanism | Trade-off |
|---|---|---|
| RDB | Periodic snapshots | Fast restart, may lose last minutes |
| AOF | Append every write | Finer durability; always/everysec/no fsync |
| Hybrid | RDB + AOF | Common production compromise |
Redis is not a durable system of record unless you engineer fsync policy and replication. Use for cache + ephemeral state; pair with Postgres for source of truth.
Eviction (allkeys-lru) when memory full — cache semantics, not database semantics.
DynamoDB: managed partitioned KV
Every table needs a primary key:
- Partition key only — one item per key value
- Partition + sort key — composite, multiple items per partition
Partitions scale independently (~10 GB soft limit per partition — hot key problem). On-demand vs provisioned capacity modes.
GSIs/LSIs — secondary access patterns with their own partition keys; eventual consistency on GSI projection lag.
Dynamo paper concepts (consistent hashing, vector clocks, sloppy quorum) → Distributed Systems → Replication & Quorums.
Graph storage
| Approach | Storage | Query |
|---|---|---|
| Adjacency list in RDBMS | edges(from_id, to_id) + indexes | Recursive CTEs — OK to ~millions of edges |
| Native graph (Neo4j) | Index-free adjacency — pointers follow edges | Fast traversals, path finding |
Graph DBs optimize relationship traversal, not bulk aggregation. Storage: nodes and relationships as records with direct pointers.
Time-series storage
Append-mostly writes, time-range reads, TTL expiration. Patterns:
- Partition by time (InfluxDB shards, TimescaleDB hypertable chunks)
- Columnar compression within chunks
- Rollups/downsamples as separate retention tiers
LSM or specialized append stores beat B-tree OLTP for ingest rate.
Picking in interviews
| Use case | Store |
|---|---|
| Session cache, rate limiting | Redis |
| Shopping cart, user settings at AWS scale | DynamoDB |
| Social graph "friends of friends" | Neo4j or adjacency + careful SQL |
| Metrics, IoT telemetry | TimescaleDB, InfluxDB, ClickHouse |
Where this goes next
HyperLogLog & Cardinality Estimation — a specialized Redis data type for a question none of the stores above answer cheaply: "how many distinct values have I seen?"
Further Reading
- Amazon Dynamo paper — consistent hashing, vector clocks, sloppy quorum, hinted handoffReference35m
- Redis Docs — Persistence (RDB snapshots vs AOF, fsync policies)Reference20m
- AWS Docs — DynamoDB Core Components (tables, items, primary key design)Reference25m
- DDIA — Ch. 2: §2.3 Graph model and Ch. 3: §3.5 Graph storage (property graphs, triple stores)Book30m
Hands-On Tasks (Optional)
Low-setup exercises — schema drills, paper walkthroughs, or optional local installs. No autograding; the goal is interview fluency on how data is stored.
- Match store to use case15m
Pick Redis, DynamoDB, Neo4j, or a time-series DB for: (a) session cache with TTL, (b) shopping cart with high write QPS, (c) friend-of-friend queries, (d) metrics with 90-day retention. One sentence each on why.