Cache key versions and invalidation events answer different questions

A cache key version and an invalidation event get treated as two ways of doing the same job: make the cache stop returning old data. They do different jobs. A version in the key protects new code from bytes it cannot read. An invalidation event tells the cache that the authoritative data changed. Mixing them up tends to produce a deploy that flushes everything and still leaves old copies sitting at the CDN.
What the key has to carry
A key should name everything that changes the answer. That usually means the environment or service, the tenant or security scope, the representation (product-summary and product-detail are different bytes), a schema generation, the identity or a digest of a canonical query, and any locale or policy dimension. Something like prod:catalog:tenant-42:product-summary:v3:product-991:en-IN.
Two parts get skipped most often. The tenant dimension is left out because "this cluster only serves one tenant", which stays true until the day it is no longer true. And query digests get computed over raw parameters, so ?sort=price&page=1 and ?page=1&sort=price become two entries. Canonicalize ordering, case and defaults before hashing, and keep personal data out of keys entirely, since keys show up in logs and admin tools.
Which version for which change
A schema generation (v3) is for when code and value shape change together. New readers look in a namespace old writers never touched, so nothing gets misparsed.
Content-addressed names suit built assets, where the content is the identity and the old name can simply live until it expires.
A generation pointer is a small token per query family. Bump it and every key in that family stops matching, with no need to enumerate them. This is the honest answer for search and list caches, where one record change affects an unknown set of results.
The trap is reaching for a global bump to fix a local change. Every key misses at once and the origin takes the whole load.
Invalidation comes from the commit
An invalidation event should be emitted after the source transaction commits, ideally through an outbox, and it should say what changed: entity identity, source version, which dimensions moved, an event ID. A message that just says "clear cache" leaves the consumer unable to tell whether it is stale.
Delivery will duplicate and reorder. A repeated delete is harmless. A late delete is not: it can evict a value that was populated after the change it describes. Storing the source version alongside the cached value, and comparing before acting, closes that. Many designs end up with a version in the key and a version in the value, since one guards compatibility and the other guards ordering.
Rolling out a new namespace
Treat a v2 to v3 move as a release. Shadow-write the new format and check serialization and key cardinality. Warm only keys with real traffic. Canary a cohort onto the new namespace, then expand, then stop writing the old one. Retire v2 only after every reader, including batch jobs, edge functions and the rollback build, has stopped touching it for a full TTL plus margin.
During all of that, protect the origin: single-flight on misses, jitter on TTLs, a cap on concurrent loads. Whether serving stale is acceptable depends on the data. For a product description it usually is. For entitlements or prices it usually is not, and those need explicit invalidation rather than a TTL alone.
Changing a Redis key does nothing to browser, proxy or CDN copies. RFC 9111 has its own freshness and validation model, and the Cache-Aside pattern only covers the application cache. Every layer that can serve the representation needs its own plan.
The full cache key versioning and invalidation guide on Edilec has the key schema table, the six-phase namespace rollout and notes on negative caching and multi-region invalidation.
Disclosure: AI assistance was used to draft this excerpt. The linked Edilec article, RFC 9111 and Microsoft's Cache-Aside documentation are the public technical sources; this excerpt does not describe a client deployment or measured Edilec result.




