Databases
Intermediate 12 min read Databases

Redis and Key-Value Stores

A very fast cache with strong opinions about what it stores

Redis serves in-memory keys with fast atomic data structures, TTLs, and pub/sub. It is a cache, a queue, and a session store — not a durable warehouse.

RedisLRUTTLevictionpub/subin-memory
Prerequisites: Choosing a Database
Before we start

What you will learn

  • Choose between in-memory serving and durable stores
  • Set TTL and eviction policies deliberately
  • Use atomic ops and clusters without extending your failure surface
Introduction

What is this?

Redis keeps a dictionary of keys in RAM, supporting strings, hashes, lists, sets, and sorted sets with atomic commands, TTLs, persistence snapshots, and pub/sub. Its speed comes from staying in memory; its durability and capacity come from a persistence config you actually configure.

Motivation

Why do you need it?

  • Every hot path (sessions, rate limits, counters, leaderboards) is a Redis use case.
  • Misconfiguring TTLs and eviction is how a 'fast cache' silently becomes stale data at churn.
  • It is one of the simplest ways to understand memory-centric workload design.
Think about it

Mental model

Imagine

A notepad next to the office coffee machine

Think of

A cache (Redis)

Fast to check, but nobody audits the notepad — if the page is stolen, nobody cares except that morning. Real truth lives in the database; the notepad is an accelerator and can be evicted.

Mechanics

How it works

  • Single-threaded event loop executes commands serially, which makes each command atomic in one instance.
  • Strings/binary/JSON, hashes for fields, lists for queues, sorted sets for rank and range queries.
  • TTL expires a key; eviction policies (allkeys-lru, volatile-lru, noeviction) decide what dies when memory is full.
  • Persistence: RDB snapshots are periodic; AOF is append-only log replayed at restart (with fsync policies).
  • Clusters shard keys by hash slot and give up multi-key transactions across slots.

Where Redis sits in a request path.

Request
Cache hit
Cache miss
Set with TTL
Eviction / TTL
Reference

Key commands

SETEX key 300 value

Set a key that lives for 300 seconds.

INCR hits / EXPIRE hits 60

Atomic counter plus a rate-limit window.

CONFIG SET maxmemory-policy allkeys-lru

Let the cache shed least-recently-used keys under pressure.

Hands-on

Examples

Cache-aside pattern with TTL

Cache-aside pattern with TTL
# read path
value = redis.get("user:123:profile")
if value is None:
value = db.query("SELECT * FROM users WHERE id=123").json # DB read
redis.setex("user:123:profile", 300, value) # 5 min TTL
# invalidation on write
db.update_user(123)
redis.delete("user:123:profile")

TTL bounds staleness; explicit delete on write keeps the cache warm and correct.

Real world

In production

  • A session store with a 24h TTL carries login state for a fleet of web nodes.
  • A rate limiter uses INCR + EXPIRE on a per-user key, capped by a second sorted-set bucket.
  • A leaderboard for a game writes ZADD and reads ZREVRANGE for top-10 in O(log n).
Guidelines

Best practices

  • Consider memory as a first-class cost: sum of key sizes × replicas should fit without thrashing.
  • Set TTLs on cache-like keys; use an explicit eviction policy that matches your freshness contract.
  • When a DB value changes, invalidate or version the key — rely on TTL as a backstop, not as the only invalidation.
  • Batch pipeline round-trips (MGET/SETEX in one call) when the LAN round trip is not free.
Watch out

Common mistakes

  • Keeping no TTL on cache entries, so stale data outlives the source and the 'cache' becomes the source of truth by accident.
  • Using noeviction on a small instance, then OOMing the host instead of evicting.
  • Putting big whole-document payloads behind single keys, blowing memory and cache hit rates.
When things break

Debugging tips

  • Redis INFO memory and keyspace_hits/miss ratio separate 'working set too large' from 'eviction too aggressive'.
  • When keys vanish, check info evicted_keys and the maxmemory policy before blaming a bug.
  • If writes vanish from the cache but the DB has them, confirm persistence is configured rather than graceful shutdown.
Interviews

Interview checkpoint

Test yourself

Quick quiz

0/2
1

A Redis RDB snapshot is a full copy that, if the process crashes mid-write, may lose recent data.

2

What happens when maxmemory is reached with policy allkeys-lru?

Go deeper

Official documentation