Ask the cache first. Only a miss goes to the database.
On a miss, read the database and store the row, with a TTL, for the next reader. A miss is slower than no cache.
10×
fewer DB reads from 90% to 99% hits
The database only sees misses, 10% versus 1%. At 50,000 reads a second that’s 5,000 versus 500, while latency barely moves.
Hold 1% of the catalogue, serve 68% of requests.
Popularity is skewed, roughly Zipf. But returns shrink fast. At α = 1.0, 80% hits needs the top 5.6% of items; 90% needs 24%.
A sale brings 200,000 reads a second. Your database comfortably serves 10,000.
The trick
You need at least 95% hits, and an empty cache asks the database for 20× its capacity.
Cache what’s reused, read far more than written, and fine slightly stale.
A seat hold or a balance before a UPI debit must be exact: read the source of truth.
A TTL bounds staleness; it doesn’t remove it
- Delete the key on write; the TTL is the backstop
- Always set one, so a missed delete heals itself
- Add jitter so keys don’t expire together
The cache dies. Now what?
Bad: Fall back to the DB
200,000 reads a second hit a database built for 10,000.
Good: Treat it as capacity
Replicate it, cap the fallback, shed the rest, serve stale where allowed.
Remember
Cache what’s reused and read-heavy, look-aside, with a TTL on every key. The hit ratio sets the database’s load, so plan for the day the cache is empty.