Cache - Cache multiple versions of a URL with Vary
- Announced
- Tags
- Cache
- Severity
- info, set by
reef/rss-rule-v1 - Source
- https://developers.cloudflare.com/changelog/post/2026-07-02-vary-for-cache-rules/
<p>Your origin can serve different responses for the same URL — different languages based on <code>Accept-Language</code>, or different formats based on <code>Accept</code> — by returning a <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-vary" target="_blank" rel="noopener"><code>Vary</code><span class="external-link"> ↗︎</span></a> response header. Cloudflare's cache now honors that header directly in <a href="https://developers.cloudflare.com/cache/how-to/cache-rules/">Cache Rules</a>, so the same URL can hold multiple cached versions and each request is matched to the right one. Content that previously had to bypass cache to stay correct can now be cached, following standard <a href="https://www.rfc-editor.org/rfc/rfc9111.html#name-calculating-cache-keys-with" target="_blank" rel="noopener">HTTP caching behavior<span class="external-link"> ↗︎</span></a>.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="what-changed">What changed</h4><a class="anchor-link" href="#what-changed"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Your origin now decides which request headers matter by listing them in its <code>Vary</code> response, and you control how Cloudflare treats each one. When you have enabled Vary using a cache rule and a response includes a <code>Vary</code> header, the request headers listed become part of the cache key.</p> <p>For each header your origin varies on, choose one of three actions:</p> <div class="table-scroll" tabindex="0" role="region" aria-label="Table"><table> <thead> <tr> <th>Action</th> <th>Behavior</th> <th>Best for</th> </tr> </thead> <tbody> <tr> <td><code>normalize</code></td> <td>Converts equivalent header values to the same cache key value before matching, collapsing redundant versions.</td> <td>Most <code>Accept</code>, <code>Accept-Language</code>, and <code>Accept-Encoding</code> use cases.</td> </tr> <tr> <td><code>passthrough</code></td> <td>Uses the raw header value to select the cached version and forwards it to the origin unchanged.</td> <td>When byte-for-byte differences in the header value should create versions.</td> </tr> <tr> <td><code>bypass</code></td> <td>Bypasses cache whenever this header name appears in the origin's <code>Vary</code> response.</td> <td>Per-user values, or headers with too many possible values to cache safely.</td> </tr> </tbody> </table></div> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="benefits">Benefits</h4><a class="anchor-link" href="#benefits"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ul> <li><strong>Higher cache hit ratios</strong>: <code>normalize</code> treats semantically equivalent headers as one version. For example, <code>Accept-Language: en-US, fr;q=0.8</code> and <code>Accept-Language: fr;q=0.8, en-GB</code> both resolve to the same cache key, so you serve more requests from cache instead of the origin.</li> <li><strong>Correct content negotiation</strong>: Requests always receive the cached version that matches their headers, so language and format variants stay accurate.</li> <li><strong>No origin or Worker changes required</strong>: If your origin already sends <code>Vary</code>, you configure the behavior entirely in Cache Rules.</li> <li><strong>Standards-aligned</strong>: Cache key calculation follows RFC 9111, and <code>Vary: *</code> continues to bypass cache as required by RFC 9110.</li> </ul> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="availability">Availability</h4><a class="anchor-link" href="#availability"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Vary in Cache Rules is available on all plans (Free, Pro, Business, and Enterprise). For per-request control in Workers subrequests, use the <a href="https://developers.cloudflare.com/workers/runtime-apis/request/#the-cfvary-property"><code>cf.vary</code></a> property.</p> <div tabindex="-1" class="heading-wrapper level-h4"><h4 id="get-started">Get started</h4><a class="anchor-link" href="#get-started"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Configure Vary in the <a href="https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules" target="_blank" rel="noopener">Cloudflare dashboard<span class="external-link"> ↗︎</span></a> under <strong>Caching</strong> > <strong>Cache Rules</strong>, or through the <a href="https://developers.cloudflare.com/ruleset-engine/rulesets-api/">Rulesets API</a>. To learn how Vary affects cache keys and how each action works, refer to <a href="https://developers.cloudflare.com/cache/concepts/vary/">Vary</a> and the <a href="https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#vary">Cache Rules Vary setting</a>.</p>
The text above is the source's. reef added the severity, the dates it could read from the text, and the endpoints and scopes named in code.