Decision guide
TTL vs Delete-on-Write vs Event-Driven Invalidation
How should cached data be kept fresh?
Side by side
| Criterion | TTL only | Delete on write (in code) | Event-driven (outbox / CDC) | Versioned keys / generations |
|---|---|---|---|---|
| Staleness window | Up to the TTL | Small, for covered writers | Pipeline lag (usually < 1 s) | Immediate after the bump |
| Covers all writers | Yes (slowly) | No | Yes | Only if every writer bumps |
| Complexity | Lowest | Low | High | Medium |
| Recovery after failures (lost messages, cache failover) | Self-healing after the TTL | Lost deletes stay stale until TTL | Replayable from the change log | One bump invalidates everything suspect |
When to choose each
TTL only
Let entries expire after a fixed time (with jitter).
Choose when
- Staleness of the TTL is acceptable
- Data changes rarely or unpredictably
- As a backstop for every other strategy
Avoid when
- Users must see their own changes immediately
- Prices, permissions, stock
Delete on write (in code)
The writer deletes affected keys after commit.
Choose when
- One service owns all writes
- Few cache owners
Avoid when
- Many writers (jobs, other services, manual SQL)
- Many caches of the same data
Event-driven (outbox / CDC)
Invalidations come from the database's change stream; each cache owner consumes them.
Choose when
- Many writers and many caches
- You need replay after failures or failovers
Avoid when
- You can't operate a broker/CDC pipeline
- Synchronous read-your-writes is required without extra routing
Versioned keys / generations
Keys embed a version or generation; bumping it makes old entries unreachable.
Choose when
- Invalidating families of keys (lists, pages)
- Deploys that change formats
- Post-failover logical flushes
Avoid when
- Memory is tight (old entries linger until TTL)
Verdict
Use TTLs everywhere as the backstop. Add delete-on-write after commit when one service owns the data, move to event-driven invalidation once several writers or caches exist, and use generations to invalidate families of keys or to flush logically after failovers.