Great breakdown of Redis caching strategies! I especially liked the emphasis on balancing speed with correctness and the reminder that Redis should reduce redundant work, not become a single point of failure as it should not be.
Redis Caching Strategies for High-Performance APIs
4 Comments
Two parts of this are each correct on their own and I think they collide, which is worth writing down because you have already done the hard thinking for both halves.
You recommend falling back to the database when Redis is unavailable. Right. You also explain the stampede. Also right. The bit that sits between them is what happens when Redis goes away: the hit rate does not degrade, it goes to zero across every key at the same instant. Using your own numbers, a system sitting at 85% hit rate with 500 queries per second reaching Postgres returns to something near the 2,000 it was doing before the cache existed, and it gets there in one step rather than over a ramp, at a moment when nothing downstream was provisioned for it. So the fallback that keeps the API functional is also the thing most likely to take the database down, which is a worse outage than the one you were avoiding.
The fix is the mechanism you already reach for on a hot key, applied at a different granularity. Single flight per key stops a thousand requests rebuilding one entry. A bounded concurrency limit on the database read path, with fast rejection once it is full, is what stops a Redis outage turning into a Postgres outage. Shedding a slice of requests with a 503 while the rest succeed is a much better afternoon than every request timing out together.
Smaller thing on redis.del after the update. Delete-on-write leaves a window: a reader can miss, read the old row, get descheduled, then your delete lands, then that reader writes its stale value back into the cache, and now the stale entry survives the full TTL with nothing left to invalidate it. It is narrow and most services genuinely never notice. If it matters, a second delete a short interval after the write closes most of it, and past that you are into versioned keys rather than deletes. Given the wallet race condition piece in your post history, I suspect this is familiar ground for you already.
@[Mike Dabydeen] This is a really valuable addition. You’re right! The fallback-to-database approach keeps the API functional, but without protection around the database path, a Redis outage can turn into a much larger downstream failure.
The distinction between per-key single-flight and bounded concurrency at the database layer is especially useful. One protects against a stampede for a specific cache key; the other protects the database when the cache itself becomes unavailable.
And good catch on the redis.del() flow as well. That stale-read --> delete --> stale-write sequence is an easy edge case to overlook when explaining cache invalidation at a high level.
This is exactly the kind of production consideration that can get lost when caching is presented as simply “check Redis, otherwise query the DB." Appreciate you taking the time to unpack it-these are exactly the kinds of production considerations that make caching much more interesting than simply putting Redis in front of a database.
Please log in to add a comment.
Please log in to comment on this post.
More Posts
- © 2026 Coder Legion
- Feedback / Bug
- Privacy
- About Us
- Contacts
- You Tube
- Tiktok
- Premium Subscription
- Terms of Service
- Early Builders
Related Jobs
- Bilingual Store Associate (Spanish)Sherwin-Williams · Full time · Hagerstown, MD
- Software Engineer, Test & Infrastructure II (Bilingual Spanish)Vail Systems · Full time · Springfield, IL
- Principal/Senior Mobile Engineer, Trading Strategies, CEXOKX · Full time · Singapore
Commenters (This Week)
Contribute meaningful comments to climb the leaderboard and earn badges!