Website Performance

Optimizing Edge Performance with Cloudflare Cache Response Rules

Optimizing Edge Performance with Cloudflare Cache Response Rules

The Core Challenge: Why Origin Headers Break Edge Caching

A Content Delivery Network (CDN) cache and an origin server operate as a collaborative pair. The primary objective is to serve content from the edge whenever possible, querying the origin only when the cache cannot fulfill the request. Every percentage point gained in your cache hit ratio (CHR) represents a direct reduction in origin bandwidth, lower infrastructure costs, and faster page load times for end users.

However, the origin server dictates how the CDN behaves. When an origin returns an asset, its response headers specify how long the CDN can store the asset, how it should be revalidated, and whether it is eligible for caching at all. If the origin misconfigures these headers, the CDN’s efficiency drops significantly.

Many caching issues manifest only after the origin replies. For example, a visitor requests a static file like /static/app.js. If Cloudflare experiences a cache miss, it forwards the request to the origin. The origin returns the file but accidentally appends a Set-Cookie header. Because of this header, the asset becomes uncacheable across Cloudflare’s global network. When multiplied across thousands of visitors, this single accidental header bypasses the cache, drives up origin bandwidth, and degrades performance.

Other common origin misconfigurations include:

  • Sending Cache-Control: no-cache on assets that are safe to cache at the edge.
  • Sending directives intended solely for the browser, not the CDN.
  • Attaching overly aggressive ETag headers that trigger unnecessary revalidation cycles on every conditional request.

In large engineering organizations, updating these headers on the origin can require weeks of cross-team coordination. Cache Response Rules solve this problem by allowing you to modify the origin’s response at the edge before it is written to Cloudflare’s cache.

Understanding the Two Phases: Request vs. Response Caching Decisions

To implement edge caching effectively, it is important to understand the distinction between the request phase and the response phase. Cloudflare handles these phases using two distinct rule types: Cache Rules and Cache Response Rules.

The Request Phase (Cache Rules)

Cache Rules run before Cloudflare contacts the origin server. They evaluate request parameters—such as the URL, file extension, request headers, geography, and device type—to answer a fundamental question: Given this request, should Cloudflare cache the response, and under what cache key?

Decisions made during this phase include:

  • Eligibility: Determining whether to cache the asset or bypass the cache entirely.
  • The Cache Key: Defining how to identify the stored object in the future.
  • Caching Parameters: Setting Edge TTL, Browser TTL, and serve-stale behavior.

These decisions must occur before the origin fetch. If a request-time rule incorrectly bypasses the cache, the latency penalty of an origin round-trip is already paid, and the response phase cannot recover that time.

The Response Phase (Cache Response Rules)

Cache Response Rules run after the origin server replies but before the response is written to Cloudflare’s cache. They answer a different question: Now that the origin has responded, should we adjust how we cache it?

This phase allows you to modify the caching behavior established during the request phase. You can strip headers that prevent caching, rewrite origin Cache-Control directives, or inject cache tags for precise purging. If a Cache Rule and a Cache Response Rule conflict, the Cache Response Rule takes precedence.

What are Cache Response Rules?

Cache Response Rules provide a declarative way to modify origin responses directly on Cloudflare’s edge, eliminating the need to write custom Cloudflare Workers or modify upstream origin code. They execute at the precise moment between receiving the origin’s response and writing that response to the cache database.

By operating in this specific window, Cache Response Rules allow you to intercept and correct headers that would otherwise invalidate the cache. This ensures that your edge caching logic remains centralized and configurable via the Cloudflare Dashboard or API.

Stripping Headers to Restore Cacheability

The set_cache_settings action allows you to remove specific headers from the origin response before Cloudflare evaluates it for caching. The primary target headers are Set-Cookie, ETag, and Last-Modified.

"action_parameters": {
  "strip_etags": true,
  "strip_set_cookie": true,
  "strip_last_modified": true
}

This configuration addresses the issue of session cookies on static assets. Application frameworks often attach session cookies to all responses by default. Stripping the Set-Cookie header in the response phase makes these assets cacheable without requiring upstream configuration changes.

Additionally, Cache Response Rules execute even on responses that are not eligible for caching. If you strip a Set-Cookie header from a dynamic response, the header is removed before the response is sent to the client, even if the asset is never stored in the cache. This provides control over the headers delivered to the client browser.

Note on Revalidation: Stripping both ETag and Last-Modified headers enables Smart Edge Revalidation for that response. However, if your Cache Response Rules strip these headers and subsequently add new validators, Cloudflare will not enable Smart Edge Revalidation for browser conditional requests.

Overriding Cache-Control Directives with Precision

The set_cache_control action allows you to modify or remove individual directives within the Cache-Control header. This includes:

  • Duration Directives: max-age, s-maxage, stale-if-error, stale-while-revalidate.
  • Qualified Directives: private, no-cache (including optional header-name qualifiers).
  • Boolean Directives: no-store, no-transform, must-revalidate, proxy-revalidate, must-understand, public, immutable.

A key feature of this action is the cloudflare_only parameter:

"action_parameters": {
  "s-maxage": {
    "operation": "set",
    "value": 86400,
    "cloudflare_only": true
  }
}

When cloudflare_only is set to true, the directive modifies how Cloudflare caches the response, but the downstream Cache-Control header sent to the browser remains unchanged. This allows you to cache an asset at the edge for a long duration (e.g., 24 hours) while instructing the browser to use a shorter cache lifetime or revalidate more frequently.

Dynamic Cache Tag Management and CDN Migration

The set_cache_tags action allows you to add, remove, or set cache tags on a response, which are used for purging content by tag. These tags can be defined statically:

"action_parameters": {
  "operation": "set",
  "values": ["product-catalog", "storefront"]
}

Alternatively, tags can be computed dynamically from an existing response header using an expression:

"action_parameters": {
  "operation": "add",
  "expression": "split(http.response.headers["Surrogate-Keys"][0], ",", 64)"
}

This dynamic approach is useful during CDN migrations. If your origin application already outputs surrogate keys using a header like Surrogate-Keys with a comma delimiter, you can parse and map them directly into Cloudflare’s Cache-Tag format during the response phase. This enables tag-based purging on Cloudflare without requiring modifications to the origin’s header output.

The third argument in the split() function defines the limit (the maximum number of elements in the resulting array, which must be between 1 and 128). Ensure this limit is set higher than the maximum number of tags expected in a single response header. A value of 1 will return the entire header as a single tag.

Practical Implementation Examples

Example 1: Strip Set-Cookie from Static Asset Extensions

This rule targets static assets that are rendered uncacheable by session cookies generated by origin middleware.

  • Expression: http.request.uri.path.extension in {"js" "css" "woff2" "woff" "ttf" "png" "jpg" "svg"}
  • Action: set_cache_settings
  • Parameters: strip_set_cookie: true

Caveat: Only apply this rule to file extensions where cookies are not required for dynamic functionality. If your origin uses cookies to vary the content of these specific static URLs, apply this rule selectively or scope it by path.

Example 2: Decouple Edge and Browser Cache Lifetimes

This rule configures Cloudflare to cache static assets for 30 days while instructing browsers to revalidate after 1 day.

  • Expression: http.request.uri.path.extension in {"js" "css" "woff2"}
  • Action: set_cache_control
  • Parameters:
    • s-maxage: set to 2592000 (30 days), cloudflare_only: true
    • max-age: set to 86400 (1 day), cloudflare_only: false
    • immutable: set

Caveat: The immutable directive instructs browsers not to revalidate the asset even on an explicit page refresh. Only pair this directive with versioned or hashed filenames (e.g., style.a8f9b2.css).

Example 3: Override no-cache on a Known-Static Path

This rule overrides default framework behaviors that apply no-cache to static directories.

  • Expression: starts_with(http.request.uri.path, "/static/") and http.response.code eq 200
  • Action: set_cache_control
  • Parameters:
    • no-cache: remove
    • s-maxage: set to 3600 (1 hour), cloudflare_only: true

Caveat: Ensure that the targeted path contains only static assets. If the directory serves user-specific or dynamic content, narrow the rule’s criteria using file extensions or content-type headers.

Example 4: Translate Cache Tags During CDN Migration

This rule extracts surrogate keys from a custom header and converts them into Cloudflare cache tags.

  • Expression: any(http.response.headers.names[*] == "Surrogate-Keys")
  • Action: set_cache_tags
  • Parameters:
    • Operation: add
    • Expression: split(http.response.headers["Surrogate-Keys"][0], ",", 64)

Key Limitations and Architectural Trade-offs

While Cache Response Rules provide significant control, they operate under specific architectural constraints:

  • No Request-Phase Modification: Cache Response Rules cannot alter the cache key or make a request cacheable if it was bypassed during the request phase. If a Cache Rule bypassed caching at request time, the response phase cannot force the asset into the cache.
  • Precedence: Cache Response Rules override conflicting directives set by Cache Rules. However, they cannot retroactively change decisions that prevented the origin request from being cached in the first place.
  • Header Stripping Trade-offs: Stripping ETag and Last-Modified headers enables Smart Edge Revalidation, but if you subsequently inject new validators via rules, Cloudflare will not enable Smart Edge Revalidation for browser conditional requests.

How to Deploy Cache Response Rules

Via the Cloudflare Dashboard

  1. Navigate to Cache > Cache Rules in the Cloudflare dashboard.
  2. Click Create rule and select Cache Response Rule.
  3. Define a descriptive name and configure your expression using request and response fields.
  4. Select your action: Modify cache-control directives, Modify cache tags, or Strip headers.
  5. When modifying directives, use the Cloudflare only toggle to apply changes exclusively to Cloudflare’s cache.
  6. Save the rule as a draft or deploy it directly to production.

Via the Cloudflare API

Cache Response Rules are managed via the Rulesets API. The rules for this phase are deployed to the following entrypoint:

/zones/{zone_id}/rulesets/phases/http_response_cache_settings/entrypoint

You can manage these rules programmatically using the API or infrastructure-as-code tools like Terraform.

Frequently asked questions

Can Cache Response Rules make a request cacheable if it was bypassed in the request phase?

No. Cache Response Rules run after the origin has responded. If a request-time Cache Rule or setting bypassed the cache, the decision is final for that request cycle. Cache Response Rules can only modify how an eligible response is cached.

What is the difference between Cache Rules and Cache Response Rules?

Cache Rules run during the request phase (before contacting the origin) and determine if an asset is eligible for caching and what its cache key should be. Cache Response Rules run during the response phase (after the origin responds) and modify how the asset is cached by stripping headers, changing Cache-Control directives, or managing cache tags.

What does the cloudflare_only parameter do?

When cloudflare_only is set to true within a Cache-Control directive, the modification applies only to Cloudflare's edge cache. The original Cache-Control header sent from the origin is passed downstream to the browser without these modifications.

How does stripping ETag and Last-Modified headers affect revalidation?

Stripping both ETag and Last-Modified headers from the origin response enables Cloudflare's Smart Edge Revalidation. However, if you use Cache Response Rules to add new validators, Cloudflare will not enable Smart Edge Revalidation for browser conditional requests.

What is the limit parameter in the split() function for cache tags?

The limit parameter defines the maximum number of elements allowed in the resulting array of tags. It must be an integer value between 1 and 128. Setting it to 1 returns the entire header string as a single tag.

Primary reference: Review the original announcement for exact release details. This article is an independent explanation and does not reproduce the source text.

Leave a Reply

Your email address will not be published. Required fields are marked *