pattern

Variant-Aware Purge

also called Tag-Based Invalidation, Vary-Safe Purge

Invalidating every cached representation of a resource rather than one URL - because content negotiation and query parameters create many objects under one address, and a URL purge clears only one of them.

cdncache-keyvaryinvalidationakamai

A price changes. The purge API returns 200 from every point of presence. Twenty minutes later customers still see the old figure, and a hard refresh fixes it for some of them.

A 200 means the purge was accepted, not that the object a customer is being served was invalidated. Purge by URL clears one cache key, and a resource commonly has many: responses that differ by Vary on encoding, language or device class, by query parameters, or by a personalisation dimension, are separate objects under the same address.

Why it matters

Invalidation is the control that lets you cache aggressively, and a control that silently works most of the time is worse than one that does not work at all. The residual stale fraction is invisible in aggregate metrics — most users see the new price, so error rates and hit ratios look normal — and it arrives as customer complaints rather than as an alert.

Implementation patterns

  • Tag objects at response time with surrogate keys naming every entity they contain: the product id, the category, the pricing version. One purge of a tag invalidates every variant in every region, whatever the URL looks like.
  • Prefer immutable addressing where anything can be renamed. A content-hashed asset or fragment is never stale and never needs purging. This is the only version of the pattern that cannot go wrong.
  • Split the TTLs: a short max-age for browsers and a long s-maxage for shared caches, because no purge reaches a browser — a long max-age is an irrevocable promise for its duration.
  • Keep the cache key deliberate. Normalise or strip query parameters that do not change the response, and vary on a device class rather than on the full user agent.
  • Monitor purge-to-visible latency with synthetic probes from several regions, so the property you depend on is measured rather than assumed.

Industry example

Every major edge network offers tag or surrogate-key invalidation alongside URL purge, and the providers document propagation in well under a second — a CDN in the mould of Akamai or Fastly propagates globally far faster than any incident timeline. When invalidation appears slow, the cause is almost never propagation: it is a key you did not purge or a cache the purge cannot reach. That diagnostic shortcut is worth more than any vendor comparison.

Failure scenarios

  • The unpurged variant, most often the compressed or the language-specific representation.
  • The browser copy, which no purge can touch, producing the "works after a hard refresh" pattern.
  • The shield or mid-tier cache, purged at the edge and not behind it, so edges refill from a stale parent.
  • stale-while-revalidate and stale-if-error windows, correctly serving the old object while a refresh happens, and read as a purge failure.
  • Tag explosion, where every object is tagged with so many keys that a common tag purges most of the cache and origin load spikes.

Trade-offs

Tags cost a response-time decision about what each object contains, and a discipline to keep tags coarse enough to be useful and fine enough to be safe. URL purge is simpler and correct only when a resource has exactly one representation. Immutable URLs are the cheapest and require the ability to change the address, which is easy for assets and hard for a canonical page.

When not to use it

For content that changes a few times a day, a 60-second TTL removes the problem entirely and costs a negligible amount of origin traffic. Invalidation machinery earns its keep when objects are expensive to generate, cached for hours, and must change immediately: prices, stock levels, published articles. Building tag propagation for a page with a two-minute TTL means the TTL was the answer.

Interview question

Q: After a price change, a fraction of users in one region still see the old price twenty minutes later, and the purge API returned success everywhere. Talk me through the diagnosis in order and the fix you would ship this week versus the one you would ship this quarter.

What a strong answer covers: reading Age, cache status and Vary from an affected client to localise the layer · recognising 20 minutes as too long for propagation and therefore the wrong hypothesis · the variant and browser-cache explanations · this week: tag-based purge and a shorter browser max-age · this quarter: immutable addressing for fragments plus a purge-to-visible synthetic probe.

Quick check

Quiz: Your purge returned 200 everywhere and the page is stale. Name the two most likely causes. A variant under the same URL that you did not purge, or a browser cache no purge can reach.

Flashcard: What does Age on a response tell you? — Which layer served it: a large Age on a hit means a surviving cached object, while Age: 0 means the origin produced the stale content.