Back to the map

Module 07 · Databases · Lesson 8 of 13

Key-value stores

The simplest data model and the fastest: a value behind a key. Why that simplicity scales so well, how key design replaces query design, in-memory versus durable stores, and the patterns that cover most uses.

IntroMust-knowJunior 9 min Updated Nov 2026

Why it matters

Every scalable system has a layer that just needs to answer "give me the thing for this id" a million times a second. Sessions, feature flags, rate-limit counters, user profiles, shopping carts, cached pages. A key-value store does exactly that and nothing else, and because it does nothing else it partitions perfectly, replicates simply and serves lookups in well under a millisecond. The skill is designing keys so that everything you need is a lookup.

The idea

A key-value store maps a unique key (usually a string or bytes) to an opaque value. The API is essentially get(key), put(key, value), delete(key), often with a time-to-live. There are no joins, no secondary queries, no schema. Data is spread across nodes by hashing the key, so capacity and throughput grow linearly with nodes and every lookup touches exactly one of them.

Key design is the whole design

Since you can only fetch by key, the key must encode the question. Conventions: a namespace prefix, the entity, and the id, such as user:42:profile or cart:session-7f3a. Composite keys answer composite questions: ratelimit:api-key-9:2026-11-08T14:07 holds this minute's counter. Lists and sets inside values (Redis hashes, lists, sorted sets; DynamoDB maps and lists) let one key hold a small collection. Anything that needs "find all users where..." is not a key-value question; either maintain an index key yourself (users-by-city:paris holding ids) or use a different store.

get(user:42)hash(key)node 1node 2node 3valueopaque bytes / JSON
Hash the key, land on one node, return the value. No scan, no join, no coordination: the shape that scales linearly.

In-memory versus durable

 In-memory (Redis, Memcached)Durable (DynamoDB, Riak, RocksDB-based)
LatencySub-millisecondSingle-digit milliseconds
DurabilityOptional snapshots or append-only log; treat as rebuildable unless configured otherwisePersisted and replicated; a system of record
CapacityBounded by RAM; cost per gigabyte is highDisk-sized; cheap per gigabyte
Data structuresRich (hashes, sorted sets, streams, pub/sub)Simpler values, sometimes with maps and lists
Typical useCaches, sessions, counters, leaderboards, locks, queuesProfiles, carts, device state, anything that must survive and scale

Patterns that cover most uses

Sessions and carts keyed by session id with a TTL. Rate limiting with atomic increments on a per-window key. Caching with cache-aside and TTLs, covered in the Caching module. Leaderboards with sorted sets. Distributed locks with set-if-not-exists plus expiry. Idempotency keys with a TTL of a day. Feature flags and configuration read on every request. Each of these is one key, one operation, and no coordination between nodes.

Consistency and scaling

Because each key lives on one partition, single-key operations can be atomic and strongly consistent cheaply; multi-key operations across partitions cannot, which is why "transactions" in key-value stores are limited or expensive. Scaling is horizontal by adding partitions; the risk is a hot key that concentrates traffic on one node, handled by splitting or caching locally. DynamoDB-style stores add a sort key within a partition, which turns the model into "find by partition, range within it" and covers many one-to-many patterns, the bridge to wide-column stores in the next lessons.

Trade-offs

Key-value stores buy speed, linear scaling and operational simplicity, and pay with the absence of queries: every access path must be designed up front as a key, and changing access patterns later means rewriting data. Use them for lookups you can name in advance and for the hot, simple parts of a system, not as the only store for data you will need to ask new questions of.

In an interview

Be concrete about keys: "Sessions in Redis keyed by session id with a 24-hour TTL, roughly one kilobyte each, so a million active sessions is a gigabyte. Rate limits are atomic increments on a per-key-per-minute counter. Both are rebuildable, so Redis runs with replicas but no strict persistence." That mix of key design, sizing and durability stance is what the question is testing.

Check yourself

A product team wants to add 'list all users in a given city' to a system whose user data lives only in a key-value store keyed by user id. What is the honest answer?

Key-value stores · Backplane