Cache stampede prevention helps stop many users from asking the database for the same data at once when the cache expires. This keeps the system fast and avoids overload.
Cache stampede prevention in Redis
SET key value NX PX milliseconds GET key DEL key
SET key value NX PX milliseconds sets a key only if it does not exist and sets expiration in milliseconds.
This helps create a lock to prevent multiple processes from regenerating cache at the same time.
SET lock_key 1 NX PX 5000
GET cache_key
DEL lock_key
This example shows how to prevent cache stampede by using a lock key. Only one process sets the lock and regenerates the cache. Others wait and retry.
GET user:123 -- If cache miss -- SET lock:user:123 1 NX PX 3000 -- If SET returns OK, regenerate cache and SET user:123 with new data DEL lock:user:123 -- Else wait and retry GET user:123
Always set a short expiration on the lock key to avoid deadlocks.
Other processes should wait and retry to get the cache instead of regenerating it.
This method reduces load on your database during high traffic.
Cache stampede prevention stops many requests from hitting the database at once.
Use Redis SET with NX and PX options to create a lock.
Only one process refreshes the cache while others wait.
Practice
Solution
Step 1: Understand cache stampede problem
Cache stampede happens when many requests try to refresh expired cache simultaneously, causing database overload.Step 2: Identify the goal of prevention
Prevention aims to allow only one process to refresh cache, reducing database hits.Final Answer:
To stop many requests from hitting the database at the same time -> Option DQuick Check:
Cache stampede prevention = stop many DB hits [OK]
- Thinking cache stampede increases cache size
- Believing cache stampede deletes cache entries
- Assuming multiple processes update cache simultaneously
Solution
Step 1: Recall Redis SET options for locking
SET with NX sets key only if it does not exist; PX sets expiration in milliseconds.Step 2: Identify correct syntax
SET key value NX PX 3000 uses SET with NX and PX correctly to create a lock with 3000ms expiry.Final Answer:
SET key value NX PX 3000 -> Option AQuick Check:
SET with NX and PX = lock with expiry [OK]
- Using GET instead of SET for locking
- Using XX instead of NX option
- Using DEL command for locking
local lock = redis.call('SET', KEYS[1], '1', 'NX', 'PX', 5000)
if not lock then
return redis.error_reply('Lock not acquired')
end
-- refresh cache here
redis.call('DEL', KEYS[1])
return 'Cache refreshed'What will be the output if the lock key already exists?
Solution
Step 1: Understand SET with NX behavior
SET with NX returns OK if key set, nil if key exists already.Step 2: Check script logic when lock not acquired
If lock is nil (not acquired), script returns redis.error_reply('Lock not acquired').Final Answer:
Lock not acquired -> Option AQuick Check:
Lock exists -> error reply 'Lock not acquired' [OK]
- Assuming script returns 'Cache refreshed' always
- Expecting nil instead of error reply
- Thinking script has syntax error
SET lock_key 1 PX NX 5000
But it does not work as expected. What is the problem?
Solution
Step 1: Check Redis SET command option order
Redis requires SET options in order: NX before PX or PX before NX is accepted, but best practice is NX PX.Step 2: Identify issue with given command
Given command uses PX before NX, which Redis does not accept; correct order is NX PX.Final Answer:
The order of PX and NX options is incorrect -> Option BQuick Check:
Correct option order is NX PX [OK]
- Thinking value '1' is invalid
- Believing SET does not support NX
- Confusing PX milliseconds with seconds
Solution
Step 1: Understand lock expiration vs refresh time
If lock expires before refresh finishes, another process may acquire lock causing duplicate refresh.Step 2: Choose approach to avoid premature lock expiration
Setting PX longer than refresh time and renewing lock prevents other processes from acquiring lock too early.Final Answer:
Set a longer PX expiration than the expected refresh time and renew the lock if needed -> Option CQuick Check:
Lock expiry > refresh time + renew if needed [OK]
- Setting too short PX causing multiple refreshes
- Not using PX expiration causing stale locks
- Using GETSET which overwrites lock unsafely
Ready to prove it?
Pass the test and this pattern moves unknown
