Caching (Cache-aside)
The cache-aside pattern (also called lazy loading) keeps your application in control of what goes into the cache and when. Redis sits in front of your database: if the data is there, great — skip the DB entirely. If not, fetch it from the DB and populate the cache for next time.
How Cache-aside Works
Section titled “How Cache-aside Works”flowchart TD
A["App needs cache:user:42"] --> B["GET cache:user:42"]
B --> C{"Cache hit?"}
C -->|"Yes"| D["Return cached value"]
C -->|"No (nil)"| E["Query DB"]
E --> F["SET cache:user:42 result EX 300"]
F --> G["Return value"] The application owns both reads and writes to the cache. Nothing is preloaded; entries are created on demand and expire automatically via the TTL.
Reading and Writing a Cache Entry
Section titled “Reading and Writing a Cache Entry”127.0.0.1:6379> GET cache:user:42(nil)127.0.0.1:6379> SET cache:user:42 "{\"name\":\"Ada\",\"email\":\"[email protected]\"}" EX 300OK127.0.0.1:6379> TTL cache:user:42(integer) 299127.0.0.1:6379> GET cache:user:42"{\"name\":\"Ada\",\"email\":\"[email protected]\"}"EX 300 sets a 300-second (5-minute) TTL. After that time the key vanishes and the next request will be a cache miss, triggering a fresh DB read.
GET cache:user:42
SET cache:user:42 "{\"name\":\"Ada\",\"email\":\"[email protected]\"}" EX 300
TTL cache:user:42
GET cache:user:42Cache Invalidation
Section titled “Cache Invalidation”When the underlying data changes — a user updates their profile, for example — the cached entry is now stale. The simplest and most reliable fix is to delete the key immediately so the next read fetches fresh data from the DB.
127.0.0.1:6379> SET cache:user:42 "{\"name\":\"Ada updated\"}" EX 300OK127.0.0.1:6379> DEL cache:user:42(integer) 1127.0.0.1:6379> GET cache:user:42(nil)SET cache:user:42 "{\"name\":\"Ada updated\"}" EX 300
DEL cache:user:42
GET cache:user:42Cache Stampede
Section titled “Cache Stampede”A cache stampede happens when a popular key expires and dozens (or thousands) of concurrent requests all get a cache miss at the same moment. They all race to the database simultaneously, producing a sudden spike in DB load — the very thing caching was meant to prevent.
Two common mitigations: use SET ... NX so only the first writer populates the key and the rest wait, or use probabilistic early expiration — a technique that randomly refreshes a key slightly before it expires based on the remaining TTL and an estimated recomputation cost. Both strategies reduce the thundering-herd effect without requiring an external lock service.