The Simplest Model
Imagine a coat check at a restaurant. You hand over your coat, receive a numbered ticket, and later present that ticket to retrieve your coat instantly. The attendant does not look inside your coat or care what is in the pockets — they just match ticket number to coat. A Key-Value Store works exactly like this: you store data under a unique key, and you retrieve it by that key. The database has no knowledge of or interest in the structure of the value.
The data model is deliberately minimal: a unique key (a string identifier) maps to a value (which can be a string, integer, binary blob, or a richer structure depending on the system). The primary operations are:
SET key value— store a valueGET key— retrieve a valueDEL key— remove a keyEXPIRE key seconds— automatically delete a key after a time-to-live (TTL)
This simplicity is the source of their power. With no schema to enforce and no relationships to traverse, key-value stores can serve millions of requests per second with sub-millisecond latency.
Common use cases:
- Session management: Store session:{session_id} → {user_id, cart, preferences} with a TTL that expires the session automatically.
- Caching: Store the result of an expensive database query under a key like product:42:details. Serve from cache; only hit the database on a cache miss.
- Rate limiting: Use atomic increment operations on a key like ratelimit:{user_id}:{minute} to count requests.
- Real-time leaderboards: Redis sorted sets allow you to maintain a ranked list of scores with O(log N) insertions and instant rank lookups.
The Champion: Redis
Redis (Remote Dictionary Server) is the dominant key-value store. It runs entirely in RAM, which is why it achieves sub-millisecond response times. Beyond simple strings, Redis supports rich data structures: lists, sets, sorted sets, hashes, bitmaps, and streams — making it far more versatile than a plain cache.
Persistence: What happens when the server restarts?
Since Redis lives in RAM, a restart would normally mean losing all data. Redis offers two persistence mechanisms:
-
RDB (Redis Database File) — Snapshot-based: Redis forks a child process that writes the entire in-memory dataset to a binary
.rdbfile on disk at configured intervals (e.g., "save every 5 minutes if at least 100 keys changed"). On restart, Redis loads this snapshot. The risk: you lose all writes since the last snapshot. -
AOF (Append-Only File) — Log-based: Every write command is appended to a log file on disk. On restart, Redis replays the log to reconstruct state. AOF can be configured to
fsyncevery second (lose at most 1 second of data) or on every write (maximum durability, lower throughput). The risk: the AOF file grows large over time and must be periodically compacted ("rewritten").
You can also enable both simultaneously: RDB for fast restarts, AOF for durability. Redis will use the AOF on restart since it is more complete.
Key Point: Redis is not just a cache — it is a data structure server. However, its in-memory nature means cost scales with dataset size. For datasets larger than available RAM, you need either Redis Cluster (horizontal sharding) or a different database category entirely. A common production mistake is using Redis as a primary database for data that should live in a durable store; treat it as a performance layer, not a source of truth, unless you have explicitly designed for that use case.