Cutting database load by 95% with a three-tier cache
VeloStore started with every product page hitting SQL Server. It worked on my laptop and wobbled the moment I load-tested it. The fix was three layers that each answer a different question.
Why three layers
An in-process memory cache answers in microseconds but only for one instance. Redis is shared across instances and survives restarts. The database stays the source of truth. A read walks Memory → Redis → Database and fills the layers on the way back.
Invalidation is the hard part
Writes must clear the right keys in every layer. I kept short TTLs on memory entries so a missed invalidation heals itself within seconds, and used explicit key names per entity so an update clears exactly what it touches.
Result
Under sustained traffic, database query load dropped by more than 95%. Measure first, cache the read path that dominates, and decide how stale each layer is allowed to be.