Ok so you've picked a write strategy. Now the other half of the problem.
How do you actually expire stale data?
Two approaches:
1. TTL-based expiry (time-to-live)
Set a timer on every cache entry. When the timer runs out, the data is automatically deleted. Next read triggers a fresh fetch.
Some rules of thumb I use:
- Config data, feature flags โ TTL of 5-10 minutes
- Product listings, search results โ TTL of 30-60 seconds
- User session data โ TTL of 30 minutes
- Versioned static assets โ TTL of 1 year (filename changes per version anyway)
Why it works: Dead simple. No extra infrastructure. Set it and forget it.
Where it breaks: You're always accepting some staleness. If the TTL is 60 seconds, a user might see outdated data for up to 60 seconds after a change. For a product listing? Nobody cares. For a bank balance? That's a support ticket.
2. Event-driven invalidation
Instead of waiting for a timer, you actively delete or update the cache the moment the underlying data changes.
How:
- Database writes trigger an event (via CDC, a message queue, or app-level hooks)
- A consumer listens for that event and invalidates the cache immediately
Why it works: Cache is always fresh. No staleness window. Precise.
Where it breaks: You need infrastructure for it. A Kafka consumer or a database change stream (Postgres logical replication, MongoDB change streams, DynamoDB streams). More moving parts. More things to monitor. More things that can fail silently.
Which one should you use?
Honestly? Start with TTL. For most data in most systems, a 30-60 second staleness window is invisible to users.
Add event-driven invalidation only for data where staleness actually costs you something:
- Inventory counts (overselling)
- Pricing (showing wrong price)
- Permissions/auth (security risk)
- Real-time features (chat, live dashboards)
Everything else? TTL. Don't over-engineer it.
Quick decision cheat sheet:
Format: What you're caching โ Strategy โ Invalidation
1) Product listings โ Write-around โ TTL (30-60s)
2) User sessions โ Write-through โ TTL (30 min)
3) Analytics counters โ Write-behind โ TTL (short)
4) Inventory / pricing โ Write-through โ Event-driven
5) Feature flags โ Write-around โ TTL (5 min)
6) User permissions โ Write-through โ Event-driven