“We’ll add Redis and it’ll fix the performance.”
Every engineer has said this. Few understand why it works — or when it catastrophically fails.
Caching is the single most powerful performance optimization you can apply. It is also the easiest way to serve stale data and have users see incorrect information for hours.
This is the Mastery Guide to Caching. We’ll cover Redis data types, the 3 eviction strategies, the hardest problem in Computer Science, and the patterns that separate seniors from juniors.
Part 1: Foundations (The Mental Model)
The Sticky Note vs. The Filing Cabinet
Every time your application needs data, it faces a choice:
The Database = The Filing Cabinet (in the basement) Accurate. Has everything. But you have to physically walk downstairs, open the drawer, find the folder, and walk back up. Slow: 5–100ms per trip.
The Cache (Redis) = The Sticky Note on your Monitor You already wrote the answer here earlier. Just look up. Fast: 0.1–1ms.
The goal: answer from the Sticky Note whenever possible. Only go to the Basement when the Sticky Note doesn’t exist or is outdated.
The Two Fundamental Questions
Every caching decision comes down to two questions:
- How long is the data “fresh”? (TTL — Time To Live)
- What happens when the cache is full? (Eviction Strategy)
Part 2: The Investigation (Redis Data Types)
Redis is not just a key-value store. It has 5 primary data structures, each solving a different problem.
| Type | Real-World Object | Use Case |
|---|---|---|
| String | A Sticky Note | Session tokens, simple cache values, counters. |
| Hash | A Mini-Spreadsheet | User profile (user:123 → {name, email, age}). |
| List | A Queue (FIFO) | Activity feed (latest 50 actions). Task queues. |
| Set | A Box of Unique Marbles | Unique visitors today. Tags on a post. |
| Sorted Set | A Ranked Leaderboard | Top 10 users by score. Rate limiting windows. |
The TTL (Time To Live)
Every cache entry should have a TTL — an expiration time. Without it, your cache is a memory leak.
| |
Part 3: The Diagnosis (Cache Invalidation — The Hardest Problem)
Phil Karlton famously said:
“There are only two hard things in Computer Science: cache invalidation and naming things.”
The 3 Eviction Strategies (When the Cache is Full)
When Redis runs out of memory, it must delete something. Which?
| Strategy | What Gets Deleted | Use When |
|---|---|---|
| LRU (Least Recently Used) | The key that hasn’t been accessed the longest. | General purpose. Safe default. (“Delete the oldest stale data”). |
| LFU (Least Frequently Used) | The key accessed the fewest times overall. | When access frequency matters. (“Viral content stays; niche stays too”). |
| FIFO (allkeys-random) | A random key. | Almost never. Dangerous. |
Set your eviction policy:
| |
The 3 Cache Failure Patterns
1. Cache Miss (Normal) Key not in cache → fetch from DB → store in cache → return. This is expected.
2. Cache Stampede (Danger) TTL expires. 10,000 users all request the same data at the same moment. All of them miss. All of them hit the DB at once. The DB collapses.
Fix: Use a lock (Redis SETNX) when regenerating a cache entry. Only one process regenerates; others wait.
| |
3. Cache Poisoning (Disaster) You cache wrong data. Now every user sees the wrong data until the TTL expires. There’s no easy fix — you must forcibly delete the key.
| |
Part 4: The Resolution (Python Cookbook)
1. The Cache-Aside Pattern (The Standard)
The application controls the cache. The most common pattern.
| |
2. Invalidate on Write (Keep the Cache Honest)
When data changes, delete the old cache entry immediately.
| |
3. Rate Limiting (Redis as Counter)
A classic use case: limit an API to 100 requests per user per minute.
| |
Final Mental Model
| |
Rules:
- Set a TTL on everything. No TTL = Memory leak.
- Invalidate cache on writes, not just by TTL.
- Cache at the right layer: Avoid caching partial data that is hard to invalidate.
