Interactive Redis Caching Strategies
Learn caching strategies hands-on — write real Redis commands that run against a live Redis instance. Try solving each challenge yourself, use hints if you get stuck, and reveal the solution when you're ready.
Strategy Challenges
Implement each caching strategy from scratch using Redis commands. Write your own commands, use hints if you get stuck, and reveal the solution when you're ready.
Cache-Aside (Lazy Loading)
✓ Pros
- •Only requested data is cached — no wasted memory
- •Cache failures are safe: app falls back to DB
- •Simple to implement with any cache store
✗ Cons
- •Cache miss costs 3 round trips (extra latency on cold start)
- •Stale data risk if DB is updated externally
- •Thundering herd on simultaneous misses
Implement the cache-aside pattern: seed a database key `db:user:1` with "Alice", attempt to read from cache key `cache:user:1` (miss), fetch from the DB and populate the cache with a 30-second TTL, verify the cache hit, then simulate a DB update and invalidate the cache.
Write-Through
✓ Pros
- •Cache is always in sync with DB — no stale reads
- •Reads are fast because data is pre-warmed in cache
- •No thundering herd on reads after a write
✗ Cons
- •Write latency is higher: must update cache + DB synchronously
- •Cache fills with data that may never be read (write amplification)
- •Two writes per operation — more complex failure handling
Implement write-through caching: write "confirmed" to both cache key `cache:order:1` (with 60s TTL) and DB key `db:order:1` simultaneously, verify both are in sync, then update the value to "shipped" in both stores.
Write-Behind (Write-Back)
✓ Pros
- •Fastest write path — ack returned before DB write completes
- •Reduces DB write load by batching multiple updates
- •Ideal for write-heavy workloads (counters, analytics)
✗ Cons
- •Data loss risk if cache crashes before flushing to DB
- •Complex to implement reliably (needs queue + retry logic)
- •DB is temporarily stale until the flush runs
Implement write-behind caching: write "12345" to cache key `cache:metric:views` with a 60s TTL (the fast path), verify the DB key `db:metric:views` is still empty, then simulate a background flush by copying the value to the DB.
Read-Through
✓ Pros
- •Simpler app code — cache handles DB fetching transparently
- •Cache auto-populates on misses (no manual population needed)
- •Single read interface for the application layer
✗ Cons
- •First read is always slow (miss forces cache to fetch from DB)
- •Cache layer must implement the fetch/populate logic
- •Harder to debug — DB access is hidden behind the cache
Implement read-through caching: seed DB key `db:product:1` with "Widget", show that the cache is empty, then have the cache layer "read through" to populate itself with a 30s TTL, and verify subsequent reads come from cache.
Predict the Output
Read the commands carefully, predict what the final command will return, then run to check your answer.
Cache Invalidation
Question: After SET, DEL, then GET — what does GET return?
Counter After INCR
Question: After setting a counter to 7 and calling INCR three times, what does GET return?
Hash Field Override
Question: After setting name to "Alice" then overwriting it to "Bob", what does HGET return?
Set Deduplication
Question: After adding "redis" to a set three times, what does SCARD (count) return?
Strategy Comparison Lab
Implement the same write scenario using two different strategies and compare the results.
Approach A: Cache-Aside Write
With cache-aside, writes go to the DB only and the cache is invalidated. Write "PriceV2" to DB key `db:item:1`, invalidate cache key `cache:item:1`, then read from cache to see the miss.
Approach B: Write-Through
With write-through, the same write updates both cache and DB. Write "PriceV2" to both `cache:item:2` (with 60s TTL) and `db:item:2`, then read from cache to see the instant hit.
Fill in the Blank
Replace the ___ placeholders with the correct Redis commands or options, then run to verify.
Store a Hash
Fill in the command to store fields in a hash and retrieve one field.
Set a TTL
Fill in the option that makes this key expire after 60 seconds.
Cache-Aside Invalidation
After updating the DB, fill in the missing command to invalidate the cache.
Sorted Set Ranking
Fill in the command to get the top 3 players in descending score order.
Real-World Mini-Projects
Apply what you've learned to real scenarios. Build each project from scratch using Redis commands.
Build a Rate Limiter
Limit a user to 5 requests per 10-second window. Initialize a counter for `ratelimit:user:42` with a 10-second TTL on the first request, increment it for subsequent requests, and show what happens when the limit is exceeded (count > 5 = HTTP 429).
Build a Session Store
Store user session data with automatic expiry. Create a session key `session:tok_abc123` with JSON user data, a 30-minute TTL (1800s), read it back to simulate authentication, then delete it to simulate logout.
Build a Leaderboard with Cache
Use a sorted set `leaderboard` for real-time rankings with players alice (1500), bob (1200), charlie (1800), diana (1650). Update bob's score by +400, view the full ranking, then cache the top-3 result as a string in `cache:leaderboard:top3` with a 10s TTL.
Bug Hunt
Each exercise has a bug. Edit the code to fix it, then run to verify the correct behavior.
Stale Cache — Missing Invalidation
This cache-aside implementation updates the DB but forgets to invalidate the cache. The cache still returns the old value "OldName". Fix it so the cache reflects the update.
Write-Through — Missing DB Write
This write-through implementation only writes to the cache. The DB never gets updated. Fix it so both are written.
Session Never Expires
This session is set without a TTL, so it never expires. A user who logs in would stay authenticated forever. Fix it by adding a reasonable expiry.