A version constant in every cache key since 2022, and what three years of using it actually looked like.
private const int CACHE_VERSION = 7;
// bumped seven times:
// 4 a serialised shape changed
// 2 a bug in what was cached, not in the shape
// 1 by accident, in a rebase
// and the accidental one cost: a cold cache at 09:00
// on a Tuesday, 400ms added to the p95 for 11 minutes.
Seven bumps in three years is roughly the rate that makes this worth having, and the accidental one is the failure mode nobody plans for — a constant in a file that is easy to touch during a merge. The overlap period is what makes it safe: old keys expire on their own TTL, so the worst case is a memory spike rather than a stampede.