Untitled Lesson
Skill Matrix
UNLOCK NODES BY LEARNING NEW TAGS.
Why is a reasonable TTL (time-to-live) still valuable on cached entries even in a system with disciplined, explicit cache invalidation on every write?
💻 Code Challenge | +75 XP
Implement a cache-aside getUser function with a 1-hour TTL, an updateUser function that explicitly invalidates the cache, and a distributed-lock-based getWithLock helper to mitigate thundering herd on a popular key.
Users occasionally saw stale profile data after updating their account settings, and a database load spike was observed whenever a popular cached product page expired. Reorder the steps to diagnose and fix both issues.
Task: Reorder the blocks in logical sequence to solve the problem.
A.D.A. Interface
Adaptive Didactic Assistant

Pascual Vila
Frontend Instructor // Code Syllabus
The Error //
Updating the underlying data without explicitly invalidating or updating the corresponding cache entry
// Wrong: cache silently serves stale data after this update
await db.users.update(userId, data);
// Correct: explicit invalidation, immediately after every write
await db.users.update(userId, data);
await redis.del(`user:${userId}`);The Solution //
The cache-aside pattern requires the application to explicitly manage cache consistency — a write path that updates the database but forgets to invalidate the cache leaves stale data being served indefinitely (or until the TTL, if any, expires), a very easy mistake to make at any one of potentially many write paths in a larger codebase.
The Error //
Having no protection against a thundering herd when a popular, frequently-requested cache key expires
// Wrong: every concurrent request independently hits the database
const cached = await redis.get(key);
if (!cached) { const fresh = await db.query(...); /* redundant, for EVERY concurrent request */ }
// Correct: only the lock-winner queries the database
const lockAcquired = await redis.set(`lock:${key}`, "1", "NX", "EX", 10);The Solution //
When many concurrent requests for the same popular key all miss the cache simultaneously (right after expiration), each one independently queries the database with the same redundant work, potentially overwhelming it with a traffic spike that wouldn't occur if the cache were still warm — a distributed lock ensures only one request repopulates the cache while others wait or fall back gracefully.