Topic 45

Key-Value Stores and Caches

NoSQL

This is the simplest database family in the whole book: a key, a value, and nothing else. You say "put this value under this name", and later you say "give me what's under that name". No tables, no relationships, no queries beyond that one — and because it does so little, it does it blindingly fast. Redis is the household name.

That narrowness sounds like a weakness until you meet the job it was born for: the cache, a fast memory layer that sits in front of the real database and answers the same question a thousand times without bothering it. And it turns out the Marquee's homepage needs exactly that.

The Whole Model in One Breath

Two operations cover it. SET stores a value under a key; GET hands it back. That's the entire vocabulary. Crucially, the store treats the value as an opaque blob — it never looks inside. To Redis, the value is a sealed parcel: it holds the parcel under the name you gave, returns it when asked, and has no idea and no opinion about what's in it.

Think of a coat check at a theater. You hand over your coat, you get a numbered tag, and later the tag gets your coat back. The attendant never opens the coat, never sorts by color, never answers "which coats have a phone in the pocket?" — and that refusal to look inside is exactly why the line moves fast. A key-value store is that coat check for data.

Why It's So Fast

Two reasons, both from doing less. First, the data usually lives in memory rather than on disk, and memory is thousands of times faster to reach. Second, the operation is a single direct lookup — no planner deciding how to run it, no rules to check, no locks to negotiate. You asked for one named thing; it hands you the one named thing.

The honest cost of living in memory: if the machine restarts, memory is wiped, so a pure in-memory store can lose what it held. Redis can be configured to save to disk and soften that, but the family's instinct is speed first, permanence second — which is fine, because its main job holds nothing it can't rebuild.

The Cache Pattern

Here's the Marquee's problem. The homepage shows "tonight's screenings", and that list comes from the query Chapter 8 made fast — a real query, but still real work, and it runs identically for every single visitor. A thousand people load the homepage in an hour and the database answers the exact same question a thousand times. Wasteful.

The cache fixes it. The first visitor's request runs the query, and the application stores the result in Redis under a key, with a lifetime attached:

Redis-dialect commands — store the result under a key, expiring in 60 seconds
SET screenings:tonight  "…the rendered list…"  EX 60
GET screenings:tonight

The EX 60 says "keep this for 60 seconds, then forget it". For the next minute, every visitor's homepage is served straight from that key — a coat-check lookup, no database work at all. After 60 seconds the key expires, the next visitor's request runs the query once more, and the cycle repeats. The database answers roughly once a minute instead of once a click.

That 60 seconds of staleness is chosen on purpose. It's the fridge whiteboard from Chapter 6 all over again — a fast running total kept beside the true source, accepted as slightly behind because glancing at it is so much cheaper than re-counting. Here the whiteboard has a 60-second timer built in, and the true source, the relational database, stays the truth.

The cache pattern — the database answers once a minute, not once a click
Visitorloads the homepage
Cache hitserved instantly, no DB
Cache miss→ run the real query
Store with EX 60refill, expire in 60s

What It Refuses to Do

The coat check's refusal to look inside is also its wall. A key-value store cannot answer "which keys hold a screening on screen 1?" — it never looks inside the parcels. No relationships, no constraints, no querying by content. If your question is anything other than "the value under this exact key", you have reached for the wrong tool, and that's not a flaw — it's the deal you signed for the speed.

Within that deal, the family has other day jobs beyond caching: holding login sessions, counting things at high speed, passing short messages between parts of a system. All the same shape — a name, a value, gone in and straight back out.

Common Confusions
  • "A cache replaces the database." The cache holds disposable copies with a lifetime; the database stays the source of truth. A cache is the purest example yet of Chapter 6's rebuildable test — wipe it entirely and you lose speed, never a single fact.
  • "60 seconds of staleness is a bug." It's the agreement. Tonight's screenings barely change, so serving a list up to a minute old is a chosen, priced, reversible trade — that's engineering, not sloppiness. Turn the timer down where freshness matters more.
  • "Key-value is primitive, so it's for toy systems." The busiest sites alive lean on it precisely because it does one thing perfectly. Narrow is not the same as small-league — the same was true of SQLite two chapters ago.
  • "The cache can answer questions about its contents." It cannot look inside the value — no "which keys contain screen 1". Ask anything but "the value under this key" and you've reached past what a key-value store does.
Why It Matters
  • The cache-in-front-of-the-database pattern runs most of the fast internet. You now recognize the architecture behind every page that loads suspiciously quickly.
  • "Copies with lifetimes, the truth stays home" completes the source-of-truth thread that has run since Chapter 5 — the cache is where it's clearest.

Knowledge Check

What does a key-value store know about the values it holds?

  • Nothing about their contents — it just holds and returns them by key
  • Their full contents, so it can sort and filter values by what's inside
  • The shape of each value, so it can enforce a schema on them
  • How its values relate to one another, like foreign keys

In the Marquee's cache pattern, what does EX 60 do?

  • It limits the key to being read 60 times before refreshing
  • It keeps the stored result for 60 seconds, then lets it expire
  • It waits 60 seconds before the value becomes available to read
  • It makes the underlying database query run in under 60 milliseconds

Redis wipes on restart and the Marquee still uses it for the homepage. Why is that acceptable?

  • The cache holds only copies; the real screenings live in the database
  • Because Redis never actually loses data on restart
  • Because the whole homepage simply isn't important enough to worry about
  • Because a second backup cache always holds the same data

Which question can a key-value store NOT answer?

  • Give me the value that is stored under screenings:tonight
  • Which stored values contain a screening on screen 1
  • Store this session under the key session:214
  • Return whatever is under the key cart:998

You got correct