Cache invalidation is a naming problem
The joke says there are two hard problems. There is really only one, and the second is the first wearing a different hat.
Invalidation is hard because it requires you to know, at write time, every identity under which a piece of data might later be requested. That is not a cache problem. That is the problem of having given the data a name that does not fully determine what it depends on — which is to say, a naming problem.
Systems that make invalidation easy all do the same thing: they make the key a function of the inputs, so that changing an input changes the key and the old entry becomes unreachable rather than wrong. Content addressing is the pure form of this. Most practical systems approximate it, and the quality of the approximation predicts how much invalidation logic they end up carrying.
You never invalidate a content-addressed cache. You simply stop asking for the old thing.
The corollary is that every explicit invalidation call in a codebase marks a place where a key failed to capture a dependency. Counting them is a surprisingly good architectural health metric, and unlike most such metrics it points directly at the fix.