---
title: Cloudflare Cache
description: Cache stores copies of frequently accessed content (such as images, videos, or webpages) in geographically distributed data centers that are located closer to end users than origin servers, reducing server load and improving website performance.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloudflare Cache

Cache content across Cloudflare's global server network.

 Available on all plans 

Cache stores copies of frequently accessed content (such as images, videos, or webpages) in geographically distributed data centers that are located closer to end users than origin servers, reducing server load and improving website performance.

## Features

### Default cache behavior

Learn about default cache behavior, default cached file extensions and cache responses.

[ Use Default cache behavior ](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/) 

### Cache Rules

Configure Cache Rules to optimize your website by specifying which resources should be cached and for how long.

[ Use Cache Rules ](https://developers.cloudflare.com/cache/how-to/cache-rules/) 

### Tiered Cache

Enable Tiered Cache to optimize content delivery by caching frequently accessed content in multiple locations for faster delivery and reduced origin traffic.

[ Use Tiered Cache ](https://developers.cloudflare.com/cache/how-to/tiered-cache/) 

### Cache Reserve

Use Cloudflare's persistent storage to increase cache times.

[ Use Cache Reserve ](https://developers.cloudflare.com/cache/advanced-configuration/cache-reserve/) 

### Purge

Instantly purge cached files to force Cloudflare to fetch fresh versions from your web server files. You can purge specific files or all at once.

[ Use Purge ](https://developers.cloudflare.com/cache/how-to/purge-cache/) 

---

## Related products

**[Load Balancing](https://developers.cloudflare.com/load-balancing/)** 

Cloudflare Load Balancing distributes traffic across your endpoints, reducing endpoint strain and latency and improving the end users experience.

**[Images](https://developers.cloudflare.com/images/)** 

A suite of products tailored to your image-processing needs.

**[Workers](https://developers.cloudflare.com/workers/)** 

Cloudflare Workers allows developers to build serverless applications and deploy instantly across the globe for exceptional performance, reliability, and scale.

**[Rules](https://developers.cloudflare.com/rules/)** 

Cloudflare Rules allows you to make adjustments to requests and responses, configure Cloudflare settings, and trigger specific actions for matching requests.

**[Cloudflare Network Interconnect](https://developers.cloudflare.com/network-interconnect/)** 

Cloudflare Network Interconnect (CNI) allows you to connect your network infrastructure directly with Cloudflare – rather than using the public Internet – for a more reliable and secure experience.

**[R2](https://developers.cloudflare.com/r2/)** 

Cloudflare R2 Storage allows developers to store large amounts of unstructured data without the costly egress bandwidth fees associated with typical cloud storage services.

**[Dedicated CDN Egress IPs](https://developers.cloudflare.com/smart-shield/configuration/dedicated-egress-ips/)** 

Smart Shield Advanced provides dedicated egress IPs (from Cloudflare to your origin) for your layer 7 WAF and CDN services, as well as Spectrum.

---

## More resources

[Plans](https://www.cloudflare.com/cdn/) 

Compare available Cloudflare plans

[Pricing](https://www.cloudflare.com/plans/#overview) 

Explore pricing options for Cache

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}}]}
```

---

---
title: Plans
description: Cloudflare provides the following features for different plans.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/plans.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Plans

Cloudflare provides the following features for different [plans ↗](https://www.cloudflare.com/plans/).

## Features

### Always Online

**Link:** [Always Online](https://developers.cloudflare.com/cache/how-to/always-online/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Crawl interval**

Available on all plans

* **Free:** Every 30 days
* **Pro:** Every 15 days
* **Business:** Every 5 days
* **Enterprise:** Every 5 days

### Browser Cache TTL

**Link:** [Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Minimum Browser Cache TTL (Page Rules)**
* **Free:** 2 minutes
* **Pro:** 2 minutes
* **Business:** 2 minutes
* **Enterprise:** 30 seconds

**Minimum Browser Cache TTL**
* **Free:** 1 second
* **Pro:** 1 second
* **Business:** 1 second
* **Enterprise:** 1 second

**Default Browser Cache TTL**
* **Free:** 4 hours
* **Pro:** 4 hours
* **Business:** 4 hours
* **Enterprise:** 4 hours

### Cache analytics

**Link:** [Cache analytics](https://developers.cloudflare.com/cache/performance-review/cache-analytics/)

**Feature availability**
* **Free:** No
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Retention period**
* **Free:** N/A
* **Pro:** 7 days
* **Business:** 30 days
* **Enterprise:** 30 days

### Cache keys

**Link:** [Cache keys](https://developers.cloudflare.com/cache/how-to/cache-keys/)

**Cache deception armor**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Cache by device type**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Ignore query string**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Sort query string**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Query string**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

**Headers**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

**Cookie**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

**Host**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

**User features**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

### Set caching level

**Link:** [Set caching level](https://developers.cloudflare.com/cache/how-to/set-caching-levels/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

### Cache reserve

**Link:** [Cache reserve](https://developers.cloudflare.com/cache/advanced-configuration/cache-reserve/)

**Feature availability**
* **Free:** Paid add-on
* **Pro:** Paid add-on
* **Business:** Paid add-on
* **Enterprise:** Paid add-on

### Cache Rules

**Link:** [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Number of rules**
* **Free:** 10
* **Pro:** 25
* **Business:** 50
* **Enterprise:** 300

### Cache by status code

**Link:** [Cache by status code](https://developers.cloudflare.com/cache/how-to/configure-cache-status-code/)

**Feature availability**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

### Crawler Hints

**Link:** [Crawler Hints](https://developers.cloudflare.com/cache/advanced-configuration/crawler-hints/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

### CSAM Scanning Tool

**Link:** [CSAM Scanning Tool](https://developers.cloudflare.com/cache/reference/csam-scanning/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

### Development mode

**Link:** [Development mode](https://developers.cloudflare.com/cache/reference/development-mode/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

### Edge Cache TTL

**Link:** [Edge Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Minimum Edge Cache TTL**
* **Free:** 2 hours
* **Pro:** 1 hour
* **Business:** 1 second
* **Enterprise:** 1 second

### ETag Headers

**Link:** [ETag Headers](https://developers.cloudflare.com/cache/reference/etag-headers/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

### Purge cache

**Link:** [Purge cache](https://developers.cloudflare.com/cache/how-to/purge-cache/)

**Feature availability**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Purge options**
* **Free:** URL, Hostname, Tag, Prefix, and Purge Everything
* **Pro:** URL, Hostname, Tag, Prefix, and Purge Everything
* **Business:** URL, Hostname, Tag, Prefix, and Purge Everything
* **Enterprise:** URL, Hostname, Tag, Prefix, and Purge Everything

### Purge limits for hostname, tag, prefix URL, and purge everything.

**Link:** [Purge limits for hostname, tag, prefix URL, and purge everything.](https://developers.cloudflare.com/cache/how-to/purge-cache/)

**Requests**

Available on all plans

* **Free:** 5 requests per minute
* **Pro:** 5 requests per second
* **Business:** 10 requests per second
* **Enterprise:** 50 requests per second

**Bucket size**
* **Free:** 25
* **Pro:** 25
* **Business:** 50
* **Enterprise:** 500

**Max operations per request**
* **Free:** 100
* **Pro:** 100
* **Business:** 100
* **Enterprise:** 100

### Single file purge

**Link:** [Single file purge](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/)

**URLs**

Available on all plans

* **Free:** 800 URLs per second
* **Pro:** 1500 URLs per second
* **Business:** 1500 URLs per second
* **Enterprise:** 3000 URLs per second

**Max operations per request**
* **Free:** 100
* **Pro:** 100
* **Business:** 100
* **Enterprise:** 500

### Query string sort

**Link:** [Query string sort](https://developers.cloudflare.com/cache/advanced-configuration/query-string-sort/)

**Feature availability**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

### Tiered cache

**Link:** [Tiered cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/)

**Tiered Cache**

Available on all plans

* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Smart Topology**
* **Free:** Yes
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

**Generic Global Topology**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

**Regional Tiered Cache**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

**Custom Topology**
* **Free:** No
* **Pro:** No
* **Business:** No
* **Enterprise:** Yes

### Vary for images

**Link:** [Vary for images](https://developers.cloudflare.com/cache/advanced-configuration/vary-for-images/)

**Feature availability**
* **Free:** No
* **Pro:** Yes
* **Business:** Yes
* **Enterprise:** Yes

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/plans/","name":"Plans"}}]}
```

---

---
title: Get started
description: Cloudflare makes customer websites faster by storing a copy of the website's content on the servers of our globally distributed data centers. Content can be either static or dynamic: static content is “cacheable” or eligible for caching, and dynamic content is “uncacheable” or ineligible for caching. The cached copies of content are stored physically closer to users, optimized to be fast, and do not require recomputing.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/get-started.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Get started

Cloudflare makes customer websites faster by storing a copy of the website's content on the servers of our globally distributed data centers. Content can be either static or dynamic: static content is “[cacheable](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions)” or eligible for caching, and dynamic content is “uncacheable” or ineligible for caching. The cached copies of content are stored physically closer to users, optimized to be fast, and do not require recomputing.

Cloudflare caches static content based on the following factors:

* [Caching levels](https://developers.cloudflare.com/cache/how-to/set-caching-levels/)
* [File extension](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions)
* Presence of [query strings](https://developers.cloudflare.com/cache/advanced-configuration/query-string-sort/)
* [Origin cache-control headers](https://developers.cloudflare.com/cache/concepts/cache-control/)
* Origin headers that indicate dynamic content
* Cache rules that bypass cache on cookie

Cloudflare only caches resources within the Cloudflare data center that serve the request. Cloudflare does not cache off-site or third-party resources, such as Facebook or Flickr, or content hosted on [unproxied (grey-clouded)](https://developers.cloudflare.com/dns/proxy-status/) DNS records.

## Learn the basics

Discover the benefits of caching with Cloudflare's CDN and understand the default cache behavior.

* [Understand what is a CDN ↗](https://www.cloudflare.com/learning/cdn/what-is-a-cdn/)
* [Understand default cache behavior](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/)
* [Understand the default file types Cloudflare caches](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions)

## Make more resources cacheable

Configure your settings to cache static HTML or cache anonymous page views of dynamic content.

* [Customize Caching with Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
* [Specify which resources to cache](https://developers.cloudflare.com/cache/concepts/customize-cache/)
* [Understand Origin Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/)
* [Cache by device type (Enterprise only)](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/cache-device-type/)

## Improve cache HIT rates

Include or exclude query strings, optimize cache keys, or enable [Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) to improve HIT rates and reduce traffic to your origin.

* [Choose a cache level](https://developers.cloudflare.com/cache/how-to/set-caching-levels/)
* [Enable Tiered Cache with Argo](https://developers.cloudflare.com/cache/how-to/tiered-cache/#enable-tiered-cache)
* [Configure custom cache keys (Enterprise only)](https://developers.cloudflare.com/cache/how-to/cache-keys/)
* [Enable Prefetch URLs (Enterprise only)](https://developers.cloudflare.com/speed/optimization/content/prefetch-urls/)

## Secure your cache configuration

Control resources a client is allowed to load and set access permissions to allow different origins to access your origin’s resources. Protect your site from web cache deception attacks while still caching static assets.

* [Avoid web cache poisoning attacks](https://developers.cloudflare.com/cache/cache-security/avoid-web-poisoning/)
* [Configure Cross-Origin Resource Sharing (CORS)](https://developers.cloudflare.com/cache/cache-security/cors/)
* [Enable Cache Deception Armor](https://developers.cloudflare.com/cache/cache-security/cache-deception-armor/#enable-cache-deception-armor)

## Cloudflare features that can alter your HTML and cacheable objects

To provide Cloudflare services to our customers, we may need to alter your HTML or cached objects to enable the feature or provide optimization.

These code alterations only occur on the cacheable objects found at Cloudflare's edge and do not affect the original source. The changes will also be removed if the specific feature is disabled and the cache is purged.

Review the list of Cloudflare features that function in this manner:

* [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/)
* [Polish](https://developers.cloudflare.com/images/polish/)
* [Hotlink Protection](https://developers.cloudflare.com/waf/tools/scrape-shield/hotlink-protection/)
* [Email address obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/)
* [Bot Management JavaScript Detections](https://developers.cloudflare.com/bots/additional-configurations/javascript-detections/)

## Troubleshoot

Resolve common caching concerns.

* [Learn about Cloudflare's cache response statuses](https://developers.cloudflare.com/cache/concepts/cache-responses/)
* [Investigate Cloudflare's cache response with cURL](https://developers.cloudflare.com/support/troubleshooting/general-troubleshooting/gathering-information-for-troubleshooting-sites/#troubleshoot-requests-with-curl)
* [Diagnose Always Online issues](https://developers.cloudflare.com/cache/troubleshooting/always-online/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/get-started/","name":"Get started"}}]}
```

---

---
title: Changelog
description: You can now control how Cloudflare handles origin responses without changing your origin. Cache Response Rules let you modify Cache-Control directives, manage cache tags, and strip headers like Set-Cookie from origin responses before they reach Cloudflare's cache. Whether traffic is cached or passed through dynamically, these rules give you control over origin response behavior that was previously out of reach.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/changelog.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Changelog

[ Subscribe to RSS ](https://developers.cloudflare.com/changelog/rss/cache.xml) 

## 2026-03-24

  
**Cache Response Rules**   

You can now control how Cloudflare handles origin responses without changing your origin. Cache Response Rules let you modify `Cache-Control` directives, manage cache tags, and strip headers like `Set-Cookie` from origin responses _before_ they reach Cloudflare's cache. Whether traffic is cached or passed through dynamically, these rules give you control over origin response behavior that was previously out of reach.

#### What changed

Cache Rules previously only operated on request attributes. Cache Response Rules introduce a new response phase that evaluates origin responses and lets you act on them before caching. You can now:

* **Modify `Cache-Control` directives**: Set or remove individual directives like `no-store`, `no-cache`, `max-age`, `s-maxage`, `stale-while-revalidate`, `immutable`, and more. For example, remove a `no-cache` directive your origin sends so Cloudflare can cache the asset, or set an `s-maxage` to control how long Cloudflare stores it.
* **Set a different browser `Cache-Control`**: Send a different `Cache-Control` header downstream to browsers and other clients than what Cloudflare uses internally, giving you independent control over edge and browser caching strategies.
* **Manage cache tags**: Add, set, or remove cache tags on responses, including converting tags from another CDN's header format into Cloudflare's `Cache-Tag` header. This is especially useful if you are migrating from a CDN that uses a different tag header or delimiter.
* **Strip headers that block caching**: Remove `Set-Cookie`, `ETag`, or `Last-Modified` headers from origin responses before caching, so responses that would otherwise be treated as uncacheable can be stored and served from cache.

#### Benefits

* **No origin changes required**: Fix caching behavior entirely from Cloudflare, even when your origin configuration is locked down or managed by a different team.
* **Simpler CDN migration**: Match caching behavior from other CDN providers without rewriting your origin. Translate cache tag formats and override directives that do not align with Cloudflare's defaults.
* **Native support, fewer workarounds**: Functionality that previously required workarounds is now built into Cache Rules with full Tiered Cache compatibility.
* **Fine-grained control**: Use expressions to match on request and response attributes, then apply precise cache settings per rule. Rules are stackable and composable with existing Cache Rules.

#### Get started

Configure Cache Response Rules in the [Cloudflare dashboard ↗](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules) under **Caching** \> **Cache Rules**, or via the [Rulesets API ↗](https://developers.cloudflare.com/ruleset-engine/rulesets-api/). For more details, refer to the [Cache Rules documentation ↗](https://developers.cloudflare.com/cache/how-to/cache-response-rules/).

## 2026-02-26

  
**Asynchronous stale-while-revalidate**   

Cloudflare's [stale-while-revalidate](https://developers.cloudflare.com/cache/concepts/cache-control/#revalidation) support is now fully asynchronous. Previously, the first request for a stale (expired) asset in cache had to wait for an origin response, after which that visitor received a REVALIDATED or EXPIRED status. Now, the first request after the asset expires triggers revalidation in the background and immediately receives stale content with an UPDATING status. All following requests also receive stale content with an `UPDATING` status until the origin responds, after which subsequent requests receive fresh content with a `HIT` status.

`stale-while-revalidate` is a `Cache-Control` directive set by your origin server that allows Cloudflare to serve an expired cached asset while a fresh copy is fetched from the origin.

Asynchronous revalidation brings:

* **Lower latency**: No visitor is waiting for the origin when the asset is already in cache. Every request is served from cache during revalidation.
* **Consistent experience**: All visitors receive the same cached response during revalidation.
* **Reduced error exposure**: The first request is no longer vulnerable to origin timeouts or errors. All visitors receive a cached response while revalidation happens in the background.

#### Availability

This change is live for all Free, Pro, and Business zones. Approximately 75% of Enterprise zones have been migrated, with the remaining zones rolling out throughout the quarter.

#### Get started

To use this feature, make sure your origin includes the `stale-while-revalidate` directive in the `Cache-Control` header. Refer to the [Cache-Control documentation](https://developers.cloudflare.com/cache/concepts/cache-control/#revalidation) for details.

## 2025-11-25

  
**Audit Logs for Cache Purge Events**   

You can now review detailed audit logs for cache purge events, giving you visibility into what purge requests were sent, what they contained, and by whom. Audit your purge requests via the Dashboard or API for all purge methods:

* Purge everything
* List of prefixes
* List of tags
* List of hosts
* List of files

#### Example

The detailed audit payload is visible within the Cloudflare Dashboard (under **Manage Account** \> **Audit Logs**) and via the API. Below is an example of the Audit Logs v2 payload structure:

```

{

  "action": {

    "result": "success",

    "type": "create"

  },

  "actor": {

    "id": "1234567890abcdef",

    "email": "user@example.com",

    "type": "user"

  },

  "resource": {

    "product": "purge_cache",

    "request": {

      "files": [

        "https://example.com/images/logo.png",

        "https://example.com/css/styles.css"

      ]

    }

  },

  "zone": {

    "id": "023e105f4ecef8ad9ca31a8372d0c353",

    "name": "example.com"

  }

}


```

#### Get started

To get started, refer to the [Audit Logs documentation](https://developers.cloudflare.com/fundamentals/account/account-security/audit-logs/).

## 2025-11-07

  
**Inspect Cache Keys with Cloudflare Trace**   

You can now see the exact cache key generated for any request directly in Cloudflare Trace. This visibility helps you troubleshoot cache hits and misses, and verify that your Custom Cache Keys — configured via Cache Rules or Page Rules — are working as intended.

Previously, diagnosing caching behavior required inferring the key from configuration settings. Now, you can confirm that your custom logic for headers, query strings, and device types is correctly applied.

Access Trace via the [dashboard](https://developers.cloudflare.com/rules/trace-request/how-to/#use-trace-in-the-dashboard) or [API](https://developers.cloudflare.com/api/resources/request%5Ftracer/methods/trace/), either manually for ad-hoc debugging or automated as part of your quality-of-service monitoring.

#### Example scenario

If you have a Cache Rule that segments content based on a specific cookie (for example, `user_region`), run a Trace with that cookie present to confirm the `user_region` value appears in the resulting cache key.

The Trace response includes the cache key in the `cache` object:

```

{

  "step_name": "request",

  "type": "cache",

  "matched": true,

  "public_name": "Cache Parameters",

  "cache": {

    "key": {

      "zone_id": "023e105f4ecef8ad9ca31a8372d0c353",

      "scheme": "https",

      "host": "example.com",

      "uri": "/images/hero.jpg"

    },

    "key_string": "023e105f4ecef8ad9ca31a8372d0c353::::https://example.com/images/hero.jpg:::::"

  }

}


```

#### Get started

To learn more, refer to the [Trace documentation](https://developers.cloudflare.com/rules/trace-request/) and our guide on [Custom Cache Keys](https://developers.cloudflare.com/cache/how-to/cache-keys/).

## 2025-08-29

  
**Smart Tiered Cache Fallback to Generic**   

[Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/#smart-tiered-cache) now falls back to [Generic Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/#generic-global-tiered-cache) when the origin location cannot be determined, improving cache precision for your content.

Previously, when Smart Tiered Cache was unable to select the optimal upper tier (such as when origins are masked by Anycast IPs), latency could be negatively impacted. This fallback now uses Generic Tiered Cache instead, providing better performance and cache efficiency.

#### How it works

When Smart Tiered Cache falls back to Generic Tiered Cache:

1. **Multiple upper-tiers**: Uses all of Cloudflare's global data centers as a network of upper-tiers instead of a single optimal location.
2. **Distributed cache requests**: Lower-tier data centers can query any available upper-tier for cached content.
3. **Improved global coverage**: Provides better cache hit ratios across geographically distributed visitors.
4. **Automatic fallback**: Seamlessly transitions when origin location cannot be determined, such as with Anycast-masked origins.

#### Benefits

* **Preserves high performance during fallback**: Smart Tiered Cache now maintains strong cache efficiency even when optimal upper tier selection is not possible.
* **Minimizes latency impact**: Automatically uses Generic Tiered Cache topology to keep performance high when origin location cannot be determined.
* **Seamless experience**: No configuration changes or intervention required when fallback occurs.
* **Improved resilience**: Smart Tiered Cache remains effective across diverse origin infrastructure, including Anycast-masked origins.

#### Get started

This improvement is automatically applied to all zones using [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/). No action is required on your part.

## 2025-04-04

  
**Workers Fetch API can override Cache Rules**   

You can now programmatically override Cache Rules using the `cf` object in the `fetch()` command. This feature gives you fine-grained control over caching behavior on a per-request basis, allowing Workers to customize cache settings dynamically based on request properties, user context, or business logic.

#### How it works

Using the `cf` object in `fetch()`, you can override specific Cache Rules settings by:

1. **Setting custom cache options**: Pass cache properties in the `cf` object as the second argument to `fetch()` to override default Cache Rules.
2. **Dynamic cache control**: Apply different caching strategies based on request headers, cookies, or other runtime conditions.
3. **Per-request customization**: Bypass or modify Cache Rules for individual requests while maintaining default behavior for others.
4. **Programmatic cache management**: Implement complex caching logic that adapts to your application's needs.

#### What can be configured

Workers can override the following Cache Rules settings through the `cf` object:

* **`cacheEverything`**: Treat all content as static and cache all file types beyond the default cached content.
* **`cacheTtl`**: Set custom time-to-live values in seconds for cached content at the edge, regardless of origin headers.
* **`cacheTtlByStatus`**: Set different TTLs based on the response status code (for example, `{ "200-299": 86400, 404: 1, "500-599": 0 }`).
* **`cacheKey`**: Customize cache keys to control which requests are treated as the same for caching purposes (Enterprise only).
* **`cacheTags`**: Append additional cache tags for targeted cache purging operations.

#### Benefits

* **Enhanced flexibility**: Customize cache behavior without modifying zone-level Cache Rules.
* **Dynamic optimization**: Adjust caching strategies in real-time based on request context.
* **Simplified configuration**: Reduce the number of Cache Rules needed by handling edge cases programmatically.
* **Improved performance**: Fine-tune cache behavior for specific use cases to maximize hit rates.

#### Get started

To get started, refer to the [Workers Fetch API documentation](https://developers.cloudflare.com/workers/runtime-apis/fetch/) and the [cf object properties documentation](https://developers.cloudflare.com/workers/runtime-apis/request/#the-cf-property-requestinitcfproperties).

## 2025-04-03

  
**All cache purge methods now available for all plans**   

You can now access all Cloudflare cache purge methods — no matter which plan you’re on. Whether you need to update a single asset or instantly invalidate large portions of your site’s content, you now have the same powerful tools previously reserved for Enterprise customers.

**Anyone on Cloudflare can now:**

1. [Purge Everything](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-everything/): Clears all cached content associated with a website.
2. [Purge by Prefix](https://developers.cloudflare.com/cache/how-to/purge-cache/purge%5Fby%5Fprefix/): Targets URLs sharing a common prefix.
3. [Purge by Hostname](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-hostname/): Invalidates content by specific hostnames.
4. [Purge by URL (single-file purge)](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/): Precisely targets individual URLs.
5. [Purge by Tag](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/): Uses Cache-Tag response headers to invalidate grouped assets, offering flexibility for complex cache management scenarios.

Want to learn how each purge method works, when to use them, or what limits apply to your plan? Dive into our [purge cache documentation](https://developers.cloudflare.com/cache/how-to/purge-cache/) and [API reference ↗](https://developers.cloudflare.com/api/resources/cache/methods/purge/) for all the details.

## 2025-02-12

  
**Configurable multiplexing HTTP/2 to Origin**   

You can now configure HTTP/2 multiplexing settings for origin connections on Enterprise plans. This feature allows you to optimize how Cloudflare manages concurrent requests over HTTP/2 connections to your origin servers, improving cache efficiency and reducing connection overhead.

#### How it works

HTTP/2 multiplexing allows multiple requests to be sent over a single TCP connection. With this configuration option, you can:

1. **Control concurrent streams**: Adjust the maximum number of concurrent streams per connection.
2. **Optimize connection reuse**: Fine-tune connection pooling behavior for your origin infrastructure.
3. **Reduce connection overhead**: Minimize the number of TCP connections required between Cloudflare and your origin.
4. **Improve cache performance**: Better connection management can enhance cache fetch efficiency.

#### Benefits

* **Customizable performance**: Tailor multiplexing settings to your origin's capabilities.
* **Reduced latency**: Fewer connection handshakes improve response times.
* **Lower origin load**: More efficient connection usage reduces server resource consumption.
* **Enhanced scalability**: Better connection management supports higher traffic volumes.

#### Get started

Enterprise customers can configure HTTP/2 multiplexing settings in the [Cloudflare Dashboard ↗](https://dash.cloudflare.com/) or through our [API](https://developers.cloudflare.com/api/).

Important consideration

This setting needs to be tuned carefully for your origin infrastructure. Setting the concurrent stream limit too high can negatively impact performance by saturating the shared TCP connection and overwhelming server processing capacity, leading to increased latency for individual requests.

## 2025-02-04

  
**Fight CSAM More Easily Than Ever**   

You can now implement our **child safety tooling**, the **[CSAM Scanning Tool](https://developers.cloudflare.com/cache/reference/csam-scanning/)**, more easily. Instead of requiring external reporting credentials, you only need a verified email address for notifications to onboard. This change makes the tool more accessible to a wider range of customers.

**How It Works**

When enabled, the tool automatically [hashes images for enabled websites as they enter the Cloudflare cache ↗](https://blog.cloudflare.com/the-csam-scanning-tool/). These hashes are then checked against a database of **known abusive images**.

* **Potential match detected?**  
   * The **content URL is blocked**, and  
   * **Cloudflare will notify you** about the found matches via the provided email address.

**Updated Service-Specific Terms**

We have also made updates to our **[Service-Specific Terms ↗](https://www.cloudflare.com/service-specific-terms-application-services/#csam-scanning-tool-terms)** to reflect these changes.

## 2025-01-08

  
**Smart Tiered Cache optimizes Load Balancing Pools**   

You can now achieve higher cache hit rates and reduce origin load when using [Load Balancing](https://developers.cloudflare.com/load-balancing/) with [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/). Cloudflare automatically selects a single, optimal tiered data center for all origins in your Load Balancing Pool.

#### How it works

When you use [Load Balancing](https://developers.cloudflare.com/load-balancing/) with [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/), Cloudflare analyzes performance metrics across your pool's origins and automatically selects the optimal Upper Tier data center for the entire pool. This means:

* **Consistent cache location**: All origins in the pool share the same Upper Tier cache.
* **Higher HIT rates**: Requests for the same content hit the cache more frequently.
* **Reduced origin requests**: Fewer requests reach your origin servers.
* **Improved performance**: Faster response times for cache HITs.

#### Example workflow

```

Load Balancing Pool: api-pool

├── Origin 1: api-1.example.com

├── Origin 2: api-2.example.com

└── Origin 3: api-3.example.com

    ↓

Selected Upper Tier: [Optimal data center based on pool performance]


```

#### Get started

To get started, enable [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) on your zone and configure your [Load Balancing Pool](https://developers.cloudflare.com/load-balancing/).

## 2024-11-20

  
**Smart Tiered Cache automatically optimizes R2 caching**   

You can now reduce latency and lower R2 egress costs automatically when using [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) with [R2](https://developers.cloudflare.com/r2/). Cloudflare intelligently selects a tiered data center close to your R2 bucket location, creating an efficient caching topology without additional configuration.

#### How it works

When you enable [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) for zones using [R2](https://developers.cloudflare.com/r2/) as an origin, Cloudflare automatically:

1. **Identifies your R2 bucket location**: Determines the geographical region where your R2 bucket is stored.
2. **Selects an optimal Upper Tier**: Chooses a data center close to your bucket as the common Upper Tier cache.
3. **Routes requests efficiently**: All cache misses in edge locations route through this Upper Tier before reaching R2.

#### Benefits

* **Automatic optimization**: No manual configuration required.
* **Lower egress costs**: Fewer requests to R2 reduce egress charges.
* **Improved hit ratio**: Common Upper Tier increases cache efficiency.
* **Reduced latency**: Upper Tier proximity to R2 minimizes fetch times.

#### Get started

To get started, enable [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) on your zone using R2 as an origin.

## 2024-11-07

  
**Stage and test cache configurations safely**   

You can now stage and test cache configurations before deploying them to production. Versioned environments let you safely validate cache rules, purge operations, and configuration changes without affecting live traffic.

#### How it works

With versioned environments, you can:

1. **Create staging versions** of your cache configuration.
2. **Test cache rules** in a non-production environment.
3. **Purge staged content** independently from production.
4. **Validate changes** before promoting to production.

This capability integrates with Cloudflare's broader [versioning system](https://developers.cloudflare.com/version-management/), allowing you to manage cache configurations alongside other zone settings.

#### Benefits

* **Risk-free testing**: Validate configuration changes without impacting production.
* **Independent purging**: Clear staging cache without affecting live content.
* **Deployment confidence**: Catch issues before they reach end users.
* **Team collaboration**: Multiple team members can work on different versions.

#### Get started

To get started, refer to the [version management documentation](https://developers.cloudflare.com/version-management/).

Important limitation

Cache Reserve is only supported for your production environment. Staged environments can use standard cache functionality, but Cache Reserve persistence is limited to production deployments.

## 2024-11-07

  
**Shard cache using custom cache key values**   

Enterprise customers can now optimize cache hit ratios for content that varies by device, language, or referrer by **sharding cache** using up to ten values from previously restricted headers with [custom cache keys](https://developers.cloudflare.com/cache/how-to/cache-keys/).

#### How it works

When configuring [custom cache keys](https://developers.cloudflare.com/cache/how-to/cache-keys/), you can now include values from these headers to create distinct cache entries:

* **`accept*` headers** (for example, `accept`, `accept-encoding`, `accept-language`): Serve different cached versions based on content negotiation.
* **`referer` header**: Cache content differently based on the referring page or site.
* **`user-agent` header**: Maintain separate caches for different browsers, devices, or bots.

#### When to use cache sharding

* Content varies significantly by device type (mobile vs desktop).
* Different language or encoding preferences require distinct responses.
* Referrer-specific content optimization is needed.

#### Example configuration

```

{

  "cache_key": {

    "custom_key": {

      "header": {

        "include": ["accept-language", "user-agent"],

        "check_presence": ["referer"]

      }

    }

  }

}


```

This configuration creates separate cache entries based on the `accept-language` and `user-agent` headers, while also considering whether the `referer` header is present.

#### Get started

To get started, refer to the [custom cache keys documentation](https://developers.cloudflare.com/cache/how-to/cache-keys/).

Note

While cache sharding can improve hit ratios for specific use cases, overly sharding your cache can reduce overall cache efficiency and negatively impact performance. Carefully evaluate whether sharding benefits your specific traffic patterns.

## 2024-09-05

  
**One-click Cache Rules templates now available**   

You can now create optimized cache rules instantly with **one-click templates**, eliminating the complexity of manual rule configuration.

#### How it works

1. Navigate to **Rules** \> **Templates** in your Cloudflare dashboard.
2. Select a template for your use case.
3. Click to apply the template with sensible defaults.
4. Customize as needed for your specific requirements.

#### Available cache templates

* **Cache everything**: Adjust the cache level for all requests.
* **Bypass cache for everything**: Bypass cache for all requests.
* **Cache default file extensions**: Replicate Page Rules caching behavior by making only default extensions eligible for cache.
* **Bypass cache on cookie**: Bypass cache for requests containing specific cookies.
* **Set edge cache time**: Cache responses with status code between 200 and 599 on the Cloudflare edge.
* **Set browser cache time**: Adjust how long a browser should cache a resource.

#### Get started

To get started, go to [**Rules > Templates** ↗](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules) in the dashboard. For more information, refer to the [Cache Rules documentation](https://developers.cloudflare.com/cache/how-to/cache-rules/).

## 2024-07-19

  
**Regionalized Generic Tiered Cache for higher hit ratios**   

You can now achieve higher cache hit ratios with [Generic Global Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/#generic-global-tiered-cache). Regional content hashing routes content consistently to the same upper-tier data centers, eliminating redundant caching and reducing origin load.

#### How it works

Regional content hashing groups data centers by region and uses consistent hashing to route content to designated upper-tier caches:

* Same content always routes to the same upper-tier data center within a region.
* Eliminates redundant copies across multiple upper-tier caches.
* Increases the likelihood of cache HITs for the same content.

#### Example

A popular image requested from multiple edge locations in a region:

* **Before**: Cached at 3-4 different upper-tier data centers
* **After**: Cached at 1 designated upper-tier data center
* **Result**: 3-4x fewer cache MISSes, reducing origin load and improving performance

#### Get started

To get started, enable [Generic Global Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/#generic-global-tiered-cache) on your zone.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/changelog/","name":"Changelog"}}]}
```

---

---
title: Cache Reserve
description: Cache Reserve is a large, persistent data store implemented on top of R2. By pushing a single button in the dashboard, your website's cacheable content will be written to Cache Reserve.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/advanced-configuration/cache-reserve.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Reserve

Smart Shield

This functionality is now offered as part of Cloudflare's origin server safeguard, Smart Shield. [Learn more](https://developers.cloudflare.com/smart-shield/).

Cache Reserve is a large, persistent data store [implemented on top of R2](https://developers.cloudflare.com/r2/). By pushing a single button in the dashboard, your website's cacheable content will be written to Cache Reserve.

In the same way that Tiered Cache builds a hierarchy of caches between your visitors and your origin, Cache Reserve serves as the ultimate upper-tier cache, that will reserve storage space for your assets for as long as you want. This ensures that your content is served from cache longer, shielding your origin from unneeded egress fees.

![Content served from origin and getting cached in Cache Reserve, and Edge Cache Data Centers \(T1=upper-tier, T2=lower-tier\) on its way back to the client](https://developers.cloudflare.com/_astro/content-being-served.6zIZl3YT_1WqRl0.webp) 

How long content in Cache Reserve will be considered “fresh” is determined by Edge Cache TTL setting or Cache-Control headers at your origin, if [Edge Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#edge-cache-ttl) is not set. After freshness expires, Cloudflare will attempt to revalidate the asset when a subsequent request arrives in Cache Reserve for the asset. This is the same behavior as in Cloudflare's regular CDN.

The retention period of an asset is how long we will keep the asset in Cache Reserve before marking it for eviction. Cache Reserve starts with a retention period of 30 days. If an asset is not requested within the retention period, it will be evicted from Cache Reserve. Accessing the asset will refresh the retention period.

Assets must [meet certain criteria](#cache-reserve-asset-eligibility) to use Cache Reserve.

Cache Reserve is a usage-based product and [pricing](#pricing) is detailed below. While Cache Reserve does require a paid plan, users can continue to use Cloudflare’s CDN (without Cache Reserve) for free.

## Enable Cache Reserve

A paid Cache Reserve Plan is required for the enablement.

* [ Dashboard ](#tab-panel-3304)
* [ API ](#tab-panel-3305)

1. In the Cloudflare dashboard, go to the **Cache Reserve** page.  
[ Go to **Cache Reserve** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-reserve)
2. Select **Enable storage sync**.

Refer to the [Change Cache Reserve setting API](https://developers.cloudflare.com/api/resources/cache/subresources/cache%5Freserve/methods/edit/) for more information.

Note

You can pause Cache Reserve at any time. Pausing Cache Reserve means that Cloudflare’s network will no longer use Cache Reserve to serve data, but resources will remain in storage until they are purged or expired.

If you are an Enterprise customer and are interested in Cache Reserve, contact your account team to get help with your configuration.

## Cache Reserve asset eligibility

Not all assets are eligible for Cache Reserve. To be admitted into Cache Reserve, assets must:

* Be cacheable, according to Cloudflare's standard [cacheability factors](https://developers.cloudflare.com/cache/).
* Have a freshness time-to-live (TTL) of at least 10 hours (set by any means such as Cache-Control / [CDN-Cache-Control](https://developers.cloudflare.com/cache/concepts/cache-control/) origin response headers, [Edge Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#edge-cache-ttl), [Cache TTL By Status](https://developers.cloudflare.com/cache/how-to/configure-cache-status-code/), or [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)),
* Have a Content-Length response header.
* When using [Image transformations](https://developers.cloudflare.com/images/manage-images/create-variants/), original files are eligible for Cache Reserve, but resized file variants are not eligible because transformations happen after Cache Reserve in the response flow.

## Limits

* Cache Reserve file limits are the same as [R2 limits](https://developers.cloudflare.com/r2/platform/limits/). Note that [CDN cache limits](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#customization-options-and-limits) still apply. Assets larger than standard limits will not be stored in the standard CDN cache, so these assets will incur Cache Reserve operations costs far more frequently.
* Origin Range requests are not supported at this time from Cache Reserve.
* [Vary for images](https://developers.cloudflare.com/cache/advanced-configuration/vary-for-images/) is currently not compatible with Cache Reserve.
* Requests to [R2 public buckets linked to a zone's domain](https://developers.cloudflare.com/r2/buckets/public-buckets/) will not use Cache Reserve. Enabling Cache Reserve for the connected zone will use Cache Reserve only for requests not destined for the R2 bucket.
* Cache Reserve makes requests for uncompressed content directly from the origin. Unlike the standard Cloudflare CDN, Cache Reserve does not include the `Accept-Encoding: gzip` header when sending requests to the origin.
* Cache Reserve is bypassed when using the Cloudflare [O2O](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/saas-customers/how-it-works/) setup.

## Usage

Like the standard CDN, Cache Reserve also uses the `cf-cache-status` header to indicate [cache response statuses](https://developers.cloudflare.com/cache/concepts/cache-responses/) like `MISS`, `HIT`, and `REVALIDATED`. Cache Reserve cache misses and hits are factored into the dashboard's cache hit ratio.

Individual sampled requests that filled or were served by Cache Reserve are viewable via the [CacheReserveUsed](https://developers.cloudflare.com/logs/logpush/logpush-job/datasets/zone/http%5Frequests/) Logpush field.

Cache Reserve monthly operations and storage usage are viewable in the dashboard.

## Pricing

Cache Reserve charges based on the total volume of data stored, along with two classes of operations on that data:

* [Class A operations](https://developers.cloudflare.com/r2/pricing/#class-a-operations) which are more expensive and tend to mutate state.
* [Class B operations](https://developers.cloudflare.com/r2/pricing/#class-b-operations) which tend to read existing state.

In most cases, a Cache Reserve miss will result in both one class A and one class B operation, and a Cache Reserve hit will result in one class B operation. Assets larger than 1 GB will incur more operations proportional to their size.

### Cache Reserve pricing

| Rates                       | |  Storage               | $0.015 / GB-month |
| --------------------------- | ------------------------ | ----------------- |
| Class A Operations (writes) | $4.50 / million requests |                   |
| Class B Operations (reads)  | $0.36 / million requests |                   |

Note

The billable quantity is rounded up to the nearest million.

### Storage usage

Storage is billed using gigabyte-month (GB-month) as the billing metric. A GB-month is calculated by recording total bytes stored for the duration of the month.

For example:

* Storing 1 GB for 30 days will be charged as 1 GB-month.
* Storing 2 GB for 15 days will be charged as 1 GB-month.

### Operations

Operations are performed by Cache Reserve on behalf of the user to write data from the origin to Cache Reserve and to pass that data downstream to other parts of Cloudflare’s network. These operations are managed internally by Cloudflare.

#### Class A operations (writes)

Class A operations are performed based on cache misses from Cloudflare’s CDN. When a request cannot be served from cache, it will be fetched from the origin and written to cache reserve as well as our edge caches on the way back to the visitor.

#### Class B operations (reads)

Class B operations are performed when data needs to be fetched from Cache Reserve to respond to a miss in the edge cache.

#### Purge

Asset purges are free operations.

Cache Reserve will be instantly purged along with edge cache when you send a purge by URL request. Refer to [cache configurations](https://developers.cloudflare.com/cache/how-to/purge-cache/) for details.

Other purge methods, such as purge by tag, host, prefix, or purge everything will force an attempt to [revalidate](https://developers.cloudflare.com/cache/concepts/cache-responses/#revalidated) on the subsequent request for the Cache Reserve asset. Note that assets purged this way will still incur storage costs until their retention TTL expires.

Note

Note this differs from the standard CDN's purge by tag, host, or prefix features which force a cache miss, requiring the origin to deliver the asset in full.

## Cache Reserve billing examples

#### Example 1

Assuming 1,000 assets (each 1 GB) are written to Cache Reserve at the start of the month and each asset is read 1,000 times, the estimated cost for the month would be:

| Usage              | Billable Quantity                         | Price           |        |
| ------------------ | ----------------------------------------- | --------------- | ------ |
| Class B Operations | (1,000 assets) \* (1,000 reads per asset) | 1,000,000       | $0.36  |
| Class A Operations | (1,000 assets) \* (1 write per asset)     | 1,000           | $4.50  |
| Storage            | (1,000 assets) \* (1GB per asset)         | 1,000 GB-months | $15.00 |
| **TOTAL**          | **$19.86**                                |                 |        |

Note

The billable quantity is rounded up to the nearest million.

#### Example 2

Assuming 1,000,000 assets (each 1 MB) are in Cache Reserve, and:

* each asset expires and is rewritten into Cache Reserve 1 time per day
* each asset is read 2 times per day

the estimated cost for the month would be:

| Usage              | Billable Quantity                                    | Price           |         |
| ------------------ | ---------------------------------------------------- | --------------- | ------- |
| Class B Operations | (1,000,000 assets) \* (2 reads per day) \* (30 days) | 60,000,000      | $21.60  |
| Class A Operations | (1,000,000 assets) \* (1 write per day) \* (30 days) | 30,000,000      | $135.00 |
| Storage            | (1,000,000 assets) \* (1MB per asset)                | 1,000 GB-months | $15.00  |
| **TOTAL**          | **$171.60**                                          |                 |         |

Note

The billable quantity is rounded up to the nearest million.

## Tips and best practices

Cache Reserve should be used with [Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) enabled. Cache Reserve is designed for use with Tiered Cache enabled for maximum origin shielding. Using Cache Reserve without Tiered Cache may result in higher storage operation costs. Enabling Cache Reserve via the Cloudflare dashboard will check and provide a warning if you try to use Cache Reserve without Tiered Cache enabled.

## Cache Reserve Analytics

Cache Reserve Analytics provides insights regarding your Cache Reserve usage. It allows you to check what content is stored in Cache Reserve, how often it is being accessed, how long it has been there and how much egress from your origin it is saving you.

In the **Overview** section, under **Cache Reserve**, you have access to the following metrics:

* **Egress savings (bandwidth)** \- is an estimation based on response bytes served from Cache Reserve that did not need to be served from your origin server. These are represented as cache hits.
* **Requests served by Cache Reserve** \- is the number of requests served by Cache Reserve (total).
* **Data storage summary** \- is based on a representative sample of requests. Refer to [Sampling](https://developers.cloudflare.com/analytics/graphql-api/sampling/) for more details about how Cloudflare samples data.  
   * **Current data stored** \- is the data stored (currently) over time.  
   * **Aggregate storage usage** \- is the total of storage used for the selected timestamp.
* **Operations** \- Class A (writes) and Class B (reads) operations over time.

## Cache Reserve clear button

You can remove all data stored in Cache Reserve through the dashboard or via API. To clear your cache reserve:

* Cache Reserve must have already been enabled for the zone.
* Cache Reserve needs to be off.

Be aware that the deletion may take up to 24 hours to complete.

* [ Dashboard ](#tab-panel-3306)
* [ API ](#tab-panel-3307)

1. In the Cloudflare dashboard, go to the **Cache Reserve** page.  
[ Go to **Cache Reserve** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-reserve)
2. In **Delete Cache Reserve Data**, select **Delete Storage**.

To delete Cache Reserve data via API use the following example requests. For more information, refer to the [API documentation](https://developers.cloudflare.com/api/resources/cache/subresources/cache%5Freserve/methods/clear/).

**Request 1: Get Cache Reserve status**

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Settings Read`
* `Zone Read`
* `Zone Write`

Get Cache Reserve setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/cache_reserve" \

  --request GET \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

Response

```

{

  "result": {

    "editable": true,

    "id": "cache_reserve",

    "value": "off"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

If Cache Reserve is turned off, you can proceed to the Cache Reserve Clear operation.

**Request 2: Start Cache Reserve Clear**

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Write`

Start Cache Reserve Clear

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/cache_reserve_clear" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

Response

```

{

  "result": {

    "id": "cache_reserve_clear",

    "start_ts": "2024-06-02T10:00:00.12345Z",

    "state": "In-progress"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/advanced-configuration/","name":"Advanced configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/advanced-configuration/cache-reserve/","name":"Cache Reserve"}}]}
```

---

---
title: Crawler Hints
description: Crawler Hints aims to increase the proportion of relevant crawls and limit crawls that do not find fresh content to reduce the need for repeated crawls.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/advanced-configuration/crawler-hints.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Crawler Hints

Crawler Hints aims to increase the proportion of relevant crawls and limit crawls that do not find fresh content to reduce the need for repeated crawls.

## Background

Search engines and similar services operate massive networks of bots that crawl the Internet to identify the content most relevant to a user query. Content on the web is always changing though, and search engine crawlers must continually wander the Internet and guess how frequently they should check a site for content updates.

With Crawler Hints, Cloudflare can proactively tell a crawler about the best time to index or when content changes. Additionally, Crawler Hints supports [IndexNow ↗](https://www.indexnow.org/), which allows websites to notify search engines whenever content on their website content is created, updated, or deleted. Crawler Hints uses cache-status [MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) to determine when content has likely been updated and sends it to IndexNow's crawler. If an asset's response has an HTTP status code greater than 4xx, the Crawler hints will not report that to [IndexNow ↗](https://www.indexnow.org/).

## Benefits

For a website owner, Crawler Hints ensures that search engines and other bot-powered experiences have the freshest version of your content, translating into happier users and ultimately influencing search rankings.

Crawler Hints also means less traffic hitting your origin, improving resource consumption, site performance, and environmental impact.

## Availability

| Free         | Pro | Business | Enterprise |     |
| ------------ | --- | -------- | ---------- | --- |
| Availability | Yes | Yes      | Yes        | Yes |

## Enable Crawler Hints

1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Enable **Crawler Hints**.

After enabling Crawler Hints, Cloudflare will begin sending hints to search engines about when they should crawl particular parts of your website.

## Prevent indexing for a specific page

When enabled, Crawler Hints is a global setting for your entire website. You can stop a specific page from being indexed by either:

* Having the origin server send through the header `X-Robots-Tag: noindex` on any pages that should not be indexed.
* Including `<meta name="robots" content="noindex, nofollow" />` in the HTML of any pages that should not be indexed.
* Creating a [Response header Transform Rule](https://developers.cloudflare.com/rules/transform/response-header-modification/) in Cloudflare to add the `X-Robots-Tag: noindex` header instead of doing it from the origin server.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/advanced-configuration/","name":"Advanced configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/advanced-configuration/crawler-hints/","name":"Crawler Hints"}}]}
```

---

---
title: Early Hints
description: Early Hints takes advantage of “server think time” to asynchronously send instructions to the browser to begin loading resources while the origin server is compiling the full response. By sending these hints to a browser before the full response is prepared, the browser can figure out how to load the webpage faster for the end user.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/advanced-configuration/early-hints.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Early Hints

Early Hints takes advantage of “server think time” to asynchronously send instructions to the browser to begin loading resources while the origin server is compiling the full response. By sending these hints to a browser before the full response is prepared, the browser can figure out how to load the webpage faster for the end user.

Formally, Early Hints is a [web standard ↗](https://httpwg.org/specs/rfc8297.html) that defines a new HTTP status code (103 Early Hints) that defines new interactions between a client and server. 103s are served to clients while a 200 OK (or error) response is prepared, which is the “server think time.” You can enable Cloudflare's edge to cache and send 103 Early Hints responses with Link headers from your HTML pages. The response contains hints about which assets will likely be needed to fully render the webpage. This "hinting" speeds up page loads and generally reduces user-perceived latency.

Note

Early Hints is currently only supported over HTTP/2 and HTTP/3.

For more information about Early Hints, refer to the [Cloudflare ↗](https://blog.cloudflare.com/early-hints) and [Google Chrome ↗](https://developer.chrome.com/en/blog/early-hints/) blogs.

## Availability

| Free         | Pro | Business | Enterprise |     |
| ------------ | --- | -------- | ---------- | --- |
| Availability | Yes | Yes      | Yes        | Yes |

## Enable Early Hints

1. In the Cloudflare dashboard, go to the **Speed** \> **Settings** page.  
[ Go to **Settings** ](https://dash.cloudflare.com/?to=/:account/:zone/speed/optimization)
2. Go to the **Content Optimization** tab.
3. For **Early Hints**, toggle the switch to **On**.

## Generate Early Hints

Early Hints are only generated and cached:

* For URIs with `.html`, `.htm`, or `.php` file extensions, or no file extension
* On 200, 301, or 302 response return codes
* When the response contains [link headers ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link) with preconnect or preload rel types, such as `Link: </img/preloaded.png>; rel=preload`

Note

Early Hints cache entries are keyed by request URI and ignore query strings.

## Emit Early Hints

Cloudflare will asynchronously look up and emit a cached 103 Early Hints response ahead of a main response.

Currently, only certain browser versions will take action to preload or preconnect on receiving Early Hints, such as Google Chrome M94 and higher. Instructions for running WebPageTest to experiment with compatible client browsers can be found in the [blog post ↗](https://blog.cloudflare.com/early-hints/#testing-early-hints-with-web-page-test).

Additionally, keep the following in mind:

* Early Hints responses may be emitted before reaching the origin server or Worker. When Early Hints is enabled and pages on your site require authentication, unauthenticated visitors may receive a 103 response. The 103 response would contain cached Link headers and be sent before a 403 Forbidden response from your origin.
* Early Hints may be emitted less frequently on requests where the content is cacheable. Cloudflare CDN is more likely to retrieve a response header before the asynchronous Early Hints lookup finishes if the response has been cached. Cloudflare will not send a 103 response if the main response header is already available.
* Cloudflare currently disables Early Hints on some User-Agents, for example, select search crawler bots that show incompatibility with 1xx responses.
* You may see an influx of `504` responses with the `RequestSource` of `earlyHintsCache` in Cloudflare Logs when Early Hints is enabled, which is expected and benign. Requests from `earlyHintsCache` are internal subrequests for cached Early Hints, and they are neither end user requests, nor do they go to your origin. Their response status only indicates whether there are cached Early Hints for the request URI (`200` on cache HIT, `504` on cache MISS). These requests are already filtered out in other views, such as Cache Analytics. To filter out these requests or to filter requests by end users of your website only, please refer to [Filter end users](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/#filter-end-users).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/advanced-configuration/","name":"Advanced configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/advanced-configuration/early-hints/","name":"Early Hints"}}]}
```

---

---
title: Query String Sort
description: Query String Sort increases cache-hit rates by first sorting query strings into a consistent order before checking the Cloudflare cache.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/advanced-configuration/query-string-sort.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Query String Sort

**Query String Sort** increases cache-hit rates by first sorting query strings into a consistent order before checking the Cloudflare cache.

By default, Cloudflare’s cache treats resources as distinct if their URL query strings are in a different order. For instance, these resources are cached separately:

* `/video/48088296?title=0&byline=0&portrait=0&color=51a516`
* `/video/48088296?byline=0&color=51a516&portrait=0&title=0`

Query String Sort changes this behavior. If two query strings exist with the same name, the URL is sorted by the parameter value. For example:

`/example/file?word=alpha&word=beta` and `/example/file?word=beta&word=alpha`

would be sorted to:

`/example/file?word=alpha&word=beta`

## Availability

| Free         | Pro | Business | Enterprise |     |
| ------------ | --- | -------- | ---------- | --- |
| Availability | No  | No       | No         | Yes |

---

## Enable Query String Sort

To enable Query String Sort:

1. Log into the [Cloudflare dashboard ↗](https://dash.cloudflare.com).
2. Select your account and zone.
3. Go to **Caching** \> **Configuration**.
4. For **Enable Query String Sort**, switch the toggle to **On**.

---

## Unexpected behavior with WordPress admin pages

When a site or an application requires exact query string ordering, enabling Query String Sort might cause unexpected behavior.

For example in the WordPress admin UI, you might notice any of the following behaviors:

* No media appear in the Media Library
* Inability to customize the site via **Appearance** \> **Customize**
* Inability to drag any widget to a sidebar in **Appearance** \> **Widgets**
* Inability to edit menus in **Appearance** \> **Menus**

To understand why this happens, note that WordPress [concatenates JavaScript files ↗](https://developer.wordpress.org/advanced-administration/wordpress/wp-config/#disable-javascript-concatenation) to speed up the administration interface. The way WordPress implements this involves multiple occurrences of `load[]` parameters in the query string, where the order of those parameters is crucial.

Note

Note that more recent versions of WordPress may not experience this issue, as a patch has been implemented in WordPress since 2019\. The patch can be found at [WordPress Core Trac Changeset 45456 ↗](https://core.trac.wordpress.org/changeset/45456).

### Identify the problem

The screenshot below shows an example where resources in the Media Library are not rendered correctly and the browser debugging console reveals that the page is throwing an error:

![Resources in the Media Library are not rendered correctly](https://developers.cloudflare.com/_astro/media_library_enabling_query.Cf3Ny9Zt_1hN0m2.webp) 

When the page `load-scripts.php` loads, the browser sends a request to Cloudflare for:

```

/wp-admin/load-scripts.php?c=0&load%5B%5D=hoverIntent,common,admin-bar,underscore,shortcode,backbone,wp-util,wp-backbone,media-models,wp-plupload,wp-mediaelement,wp-api-r&load%5B%5D=equest,media-views,media-editor,media-audiovideo,mce-view,imgareaselect,image-edit,media-grid,media,svg-painter&ver=5.0.3


```

With Query String Sort enabled, Cloudflare will then sort the parameters and values in the request query string, resulting in the following:

```

/wp-admin/load-scripts.php?c=0&load%5B%5D=equest,media-views,media-editor,media-audiovideo,mce-view,imgareaselect,image-edit,media-grid,media,svg-painter&load%5B%5D=hoverIntent,common,admin-bar,underscore,shortcode,backbone,wp-util,wp-backbone,media-models,wp-plupload,wp-mediaelement,wp-api-r&ver=5.0.3


```

Note that the `load[]` parameters were swapped, as `equest` should come before `hoverIntent` when alphabetically ordered.

When this happens, you will most likely find errors in the browser console, such as:

`_____ is not defined at load-scripts.php?c=0&load[]=...`

This type of error indicates that Query String Sort is inadvertently breaking some WordPress admin page functionality.

After sorting, the query then goes to Cloudflare's cache infrastructure (and to the origin server, if the resource is not in the Cloudflare cache or is not cacheable). The origin server then serves the concatenated scripts, which are ordered differently. Because scripts might depend on other scripts, this process might break dependencies.

### Respond to the issue

Start by analyzing your site or application behavior around the use of query strings. Do you have assets served with multiple possible arrangements of query strings?

For example, you might have an image resizing endpoint or a search form, where the order of query parameters might vary - such as width, height, and version - yet a unique parameter combination points to a single relevant asset.

To minimize problems, consider:

* Disabling **Query String Sort** for the site if you’re sure that this feature does not add value to any part of your site. Cloudflare disables this option by default in the **Caching** app.
* Use Cache Rules to enable **Query String Sort** (set **Cache key** \> **Sort query string**: `On`) for URLs where preserving the query string parameter order is not important.
* Alternatively, use Cache Rules to disable **Query String Sort** for URLs where a specific parameter order is required. For example, set **Cache key** \> **Sort query string**: `Off` for URI paths starting with `/wp-admin/load-scripts.php`, or for any URLs with similar requirements.

To learn more about Cache Rules, visit [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/).

---

## Related resources

* [Increasing Cache Hit Rates with Query String Sort ↗](https://blog.cloudflare.com/increasing-cache-hit-rates-with-query-string-sort/)
* [Best Practice: Caching Everything While Ignoring Query Strings](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/cache-everything-ignore-query-strings/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/advanced-configuration/","name":"Advanced configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/advanced-configuration/query-string-sort/","name":"Query String Sort"}}]}
```

---

---
title: Serving tailored content with Cloudflare
description: Content negotiation is the practice of serving different versions of a resource from a single URL, tailoring the experience to the end user. Common examples include delivering content in a specific language (Accept-Language), optimizing for a device (User-Agent), or serving modern image formats (Accept).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/advanced-configuration/serve-tailored-content.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Serving tailored content with Cloudflare

Content negotiation is the practice of serving different versions of a resource from a single URL, tailoring the experience to the end user. Common examples include delivering content in a specific language (`Accept-Language`), optimizing for a device (`User-Agent`), or serving modern image formats (`Accept`).

Cloudflare's global network is designed to handle this at scale. For common scenarios such as serving next-generation images, this negotiation is streamlined with a dedicated feature. For more customized logic, Cloudflare provides a toolkit including Transform Rules, Snippets, Custom Cache Keys, and Workers, giving you granular control to ensure the right content is served to every user, every time.

---

## Use query strings

The [Transform Rule](https://developers.cloudflare.com/rules/transform/) method is ideal when you can create a distinct URL, such as serving content based on a visitor's location.

### Geolocation example

In this example, you run an e-commerce site and want to display prices in the local currency based on the visitor's country.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** and select the option **URL Rewrite Rule**.
3. Enter a descriptive name, such as `Vary by Country - Canada`.
4. In **If incoming requests match...**, select **Custom filter expression**.
5. Under **When incoming requests match...**, create the following expression:  
   * **Field:** `Country`  
   * **Operator:** `equals`  
   * **Value:** `Canada`
6. Under **Then...**  
   * for **Path**, select **Preserve**.  
   * for **Query**, select **Rewrite to**: **Dynamic** `loc=ca`
7. Select **Save**.

Now, requests from Canada to `/products/item` will be transformed to `/products/item?loc=ca` before reaching your origin or the cache, creating a distinct cache entry.

Availability

Free, Pro, Business, and Enterprise plans

---

## Vary for Images

[Vary for Images](https://developers.cloudflare.com/cache/advanced-configuration/vary-for-images/) tells Cloudflare which variants your origin supports. Cloudflare then caches each version separately and serves the correct one to browsers without contacting your origin each time. This feature is managed via the Cloudflare API.

### Enable Vary for Images

To enable this feature, create a _variants rule_ using the API. This rule maps file extensions to the image formats your origin can serve.

For example, the following API call tells Cloudflare that for `.jpeg` and `.jpg` files, your origin can serve `image/webp` and `image/avif` variants:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Write`

Change variants setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/variants" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "value": {

        "jpeg": [

            "image/webp",

            "image/avif"

        ],

        "jpg": [

            "image/webp",

            "image/avif"

        ]

    }

  }'


```

After creating the rule, Cloudflare will create distinct cache entries for each image variant, improving performance for users with modern browsers.

Availability

Pro, Business, and Enterprise plans

## Use Snippets for programmatic caching

[Snippets](https://developers.cloudflare.com/rules/snippets/) are self-contained JavaScript fetch handlers that run at the edge on your requests through Cloudflare. They allow you to programmatically interact with the cache, providing full control over the cache key and response behavior without changing the user-facing URL.

### Example: A/B testing

In this example, you run an A/B test controlled by a cookie named `ab-test` (with values `group-a` or `group-b`). You want to cache a different version of the page for each group.

1. In the Cloudflare dashboard, go to the **Snippets** page.  
[ Go to **Snippets** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/snippets)
2. Select **Create new Snippet** and name it `ab-test-caching`.
3. Paste the following code. It modifies the cache key based on the `ab-test` cookie and caches the response for 30 days.

JavaScript

```

const CACHE_DURATION = 30 * 24 * 60 * 60; // 30 days


export default {

  async fetch(request) {

    // Construct a new URL for the cache key based on the A/B cookie

    const abCookie = request.headers.get('Cookie')?.match(/ab-test=([^;]+)/)?.[1] || 'control';

    const url = new URL(request.url);

    url.pathname = `/ab-test/${abCookie}${url.pathname}`;


    const cacheKey = new Request(url, request);

    const cache = caches.default;


    let response = await cache.match(cacheKey);

    if (!response) {

      // If not in cache, fetch from origin

      response = await fetch(request);

      response = new Response(response.body, response);

      response.headers.set("Cache-Control", `s-maxage=${CACHE_DURATION}`);

      // Put the response into cache with the custom key

      await cache.put(cacheKey, response.clone());

    }

    return response;

  },

};


```

1. Save and deploy the Snippet.
2. From the Snippets dashboard, select **Attach to routes** to assign the Snippet.

Availability

Pro, Business, and Enterprise plans

## Custom Cache Keys (Enterprise)

If your account is on an Enterprise plan, the [Custom Cache Keys](https://developers.cloudflare.com/cache/how-to/cache-keys) feature provides a no-code interface to define which request properties are included in the cache key.

Custom Cache Key options:

* Cache by device type
* Query string option `No query string parameters except`
* Include headers and values
* Include cookie names and values
* User: Device type, Country, Language

### Example: Same URL, different content

If your origin serves different content types (for example, `application/json` vs. `text/html`) at the same URL based on the `Accept` header, use a custom cache key to cache them separately.

1. In the Cloudflare dashboard, go to the **Cache Rules** page.  
[ Go to **Cache Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules)
2. Select **Create rule**.
3. Enter rule name, such as `Vary by Accept Header`.
4. Set the condition for the rule to apply (for example, a specific hostname or path).
5. Under **Cache key**, select **Use custom key**.
6. Select **Add new**.  
   * **Type**: `Header`  
   * **Name**: `Accept`  
   * **Value**: Add each `value`, or leave empty for all.
7. Select **Deploy**.

This configuration creates separate cache entries based on the `Accept` header value, respecting your API's content negotiation.

Availability

Enterprise plans only

## Use Cloudflare Workers for advanced logic

For complex caching scenarios, [Cloudflare Workers](https://developers.cloudflare.com/cache/interaction-cloudflare-products/workers/) provide a full serverless environment ideal for custom logic at scale.

### Example: Device type – Free/Pro/Biz (without Tiered Cache)

This Worker detects whether a visitor is on a mobile or desktop device and creates separate cache entries for each, ensuring the correct version of the site is served and cached.

JavaScript

```

export default {

  async fetch(request, env, ctx) {

    const userAgent = request.headers.get('User-Agent') || '';

    const deviceType = userAgent.includes('Mobile') ? 'mobile' : 'desktop';


    // Create a new URL for the cache key that includes the device type

    const url = new URL(request.url);

    url.pathname = `/${deviceType}${url.pathname}`;


    const cacheKey = new Request(url, request);

    const cache = caches.default;


    let response = await cache.match(cacheKey);


    if (!response) {

      console.log(`Cache miss for ${deviceType} device. Fetching from origin.`);

      response = await fetch(request);

      let responseToCache = response.clone();

      ctx.waitUntil(cache.put(cacheKey, responseToCache));

    }


    return response;

  },

};


```

Availability

Free and Paid plans

### Example: Device type – Enterprise (with Tiered Cache)

This Worker detects if a visitor is on a mobile device or a desktop and creates a separate cache entry for each, ensuring the correct version of the site is served and cached. Uses the Enterprise `cf.customCacheKey` feature.

JavaScript

```

export default {

  async fetch(request) {

    // 1. Determine the device type from the User-Agent header

    const userAgent = request.headers.get('User-Agent') || '';

    const deviceType = userAgent.includes('Mobile') ? 'mobile' : 'desktop';


    // 2. Create a custom cache key by appending the device type to the URL

    const customCacheKey = `${request.url}-${deviceType}`;


    // 3. Fetch the response. Cloudflare's cache automatically uses the

    //    customCacheKey for cache operations (match, put).

    const response = await fetch(request, {

      cf: {

        cacheKey: customCacheKey,

      },

    });


    // Optionally, you can modify the response before returning it

    // For example, add a header to indicate which cache key was used

    const newResponse = new Response(response.body, response);

    newResponse.headers.set("X-Cache-Key", customCacheKey);

    return newResponse;

  },

};


```

Availability

Enterprise only

## Example: Caching Next.js RSC payloads

A common challenge is caching content from frameworks like Next.js, which uses an `RSC` (React Server Components) request header to differentiate between HTML page loads and RSC data payloads for the same URL. Here are the best ways to handle this.

### Method 1: Transform Rules

The simplest solution is to create a [Transform Rule](https://developers.cloudflare.com/rules/transform/) that checks for the `RSC` header and adds a unique query parameter on the request, creating two distinct cacheable URLs: `/page` (for HTML) and `/page?_rsc=1` (for the RSC payload).

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** and select the option **URL Rewrite Rule**.
3. Enter a name, such as `Vary by RSC Header`.
4. In **If incoming requests match**, select **Custom filter expression**.
5. Under **When incoming requests match**, manually edit the expression so that it checks for the presence of the `RSC` header:  
   * `has_key(http.request.headers, "rsc")`
6. Under **Then**:  
   * For **Path**, select **Preserve**.  
   * For **Query**, select **Rewrite to**, select **Static**: `_rsc=1`.
7. Select **Save**.

### Method 2: Snippets or Custom Cache Keys

Alternatively, use [Snippets](https://developers.cloudflare.com/rules/snippets/) or [Custom Cache Keys](https://developers.cloudflare.com/cache/how-to/cache-keys) to add the `RSC` header directly to the cache key without modifying the visible URL. This provides a cleaner URL but requires more advanced configuration.

Availability

* Snippets: Pro, Business, Enterprise
* Custom Cache Keys: Enterprise only

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/advanced-configuration/","name":"Advanced configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/advanced-configuration/serve-tailored-content/","name":"Serving tailored content with Cloudflare"}}]}
```

---

---
title: Vary for images
description: Vary is an HTTP response header that allows origins to serve variants of the same content that can be used depending on the browser sending the request.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/advanced-configuration/vary-for-images.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Vary for images

`Vary` is an HTTP response header that allows origins to serve variants of the same content that can be used depending on the browser sending the request.

Cloudflare sits in between the browser and the origin. When Cloudflare receives the origin’s response, the specific image variant is cached so that subsequent requests from browsers with the same image preferences can be served from cache. This also means that serving multiple image variants for the same asset will create distinct cache entries.

`Vary` for Images reduces the content-negotiation process by parsing a request’s `Accept` header, which is sent to the origin to deliver the correct content to the browser.

Vary for images is available for Pro, Business, and Enterprise customers.

## Availability

| Free         | Pro | Business | Enterprise |     |
| ------------ | --- | -------- | ---------- | --- |
| Availability | No  | Yes      | Yes        | Yes |

## File extensions

You can use vary for images on the file extensions below if the origin server sends the `Vary: Accept` response header. If the origin server sends `Vary: Accept` but does not serve the set variant, the response is not cached and displays `BYPASS` in the cache status in the response header. Additionally, the list of variant types the origin serves for each extension must be configured so that Cloudflare decides which variant to serve without contacting the origin server.

File extensions enabled for varying

* .avif
* .bmp
* .gif
* .jpg
* .jpeg
* .jp2
* .png
* .tif
* .tiff
* .webp

## Enable vary for images

Vary for Images is enabled through Cloudflare’s API by creating a variants rule. In the examples below, learn how to serve JPEG, WebP, and AVIF variants for `.jpeg` and `.jpg` extensions.

### Create a variants rule

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Write`

Change variants setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/variants" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "value": {

        "jpeg": [

            "image/webp",

            "image/avif"

        ],

        "jpg": [

            "image/webp",

            "image/avif"

        ]

    }

  }'


```

### Modify to only allow WebP variants

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Write`

Change variants setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/variants" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "value": {

        "jpeg": [

            "image/webp"

        ],

        "jpg": [

            "image/webp"

        ]

    }

  }'


```

### Delete the rule

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Write`

Delete variants setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/variants" \

  --request DELETE \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

### Get the rule

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Settings Read`
* `Zone Read`
* `Zone Write`

Get variants setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/variants" \

  --request GET \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

To learn more about purging varied images, refer to [Purge varied images](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-varied-images/).

## Limitations

* For Vary for images to work, your image URLs must include the file extension in the path and not the query string. For example the URL `https://example.com/image.jpg` is compatible but `https://example.com/index.php?file=image.jpg` is not compatible.
* Your origin must return an image type matching the file extension in the URL when a HTTP client sends no `Accept` header, or an `Accept: */*` header. Otherwise, you will see `CF-Cache-Status: BYPASS` in the HTTP response headers.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/advanced-configuration/","name":"Advanced configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/advanced-configuration/vary-for-images/","name":"Vary for images"}}]}
```

---

---
title: Avoid web cache poisoning
description: A cache poisoning attack uses an HTTP request to trick an origin web server into responding with a harmful resource that has the same cache key as a clean request. As a result, the poisoned resource gets cached and served to other users.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/cache-security/avoid-web-poisoning.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Avoid web cache poisoning

A cache poisoning attack uses an HTTP request to trick an origin web server into responding with a harmful resource that has the same cache key as a clean request. As a result, the poisoned resource gets cached and served to other users.

A Content Delivery Network (CDN) like Cloudflare relies on cache keys to compare new requests against cached resources. The CDN then determines whether the resource should be served from the cache or requested directly from the origin web server.

## Learn about Cache Poisoning

To deepen your understanding of the risks and vulnerabilities associated with cache poisoning, consult the following resources:

* [Practical Web Cache Poisoning ↗](https://portswigger.net/blog/practical-web-cache-poisoning)
* [How Cloudflare protects customers from cache poisoning ↗](https://blog.cloudflare.com/cache-poisoning-protection/)

## Only cache files that are truly static

Review the caching configuration for your origin web server and ensure you are caching files that are static and do not depend on user input in any way. To learn more about Cloudflare caching, review:

* [Which file extensions does Cloudflare cache for static content?](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/)
* [How Do I Tell Cloudflare What to Cache?](https://developers.cloudflare.com/cache/how-to/cache-rules/)

## Do not trust data in HTTP headers

Client-side vulnerabilities are often exploited through HTTP headers, including cross-site scripting (XSS). In general, you should not trust the data in HTTP headers and as such:

* Do not rely on values in HTTP headers if they are not part of your [cache key](https://developers.cloudflare.com/cache/how-to/cache-keys/).
* Never return HTTP headers to users in cached content.

## Do not trust GET request bodies

Cloudflare caches contents of GET request bodies, but they are not included in the cache key. GET request bodies should be considered untrusted and should not modify the contents of a response. If a GET body can change the contents of a response, consider bypassing cache or using a POST request.

## Monitor web security advisories

To keep informed about Internet security threats, Cloudflare recommends that you monitor web security advisories on a regular basis. Some of the more popular advisories include:

* [Drupal Security Advisories ↗](https://www.drupal.org/security)
* [Symfony Security Advisories ↗](https://symfony.com/blog/category/security-advisories)
* [Laminas Security Advisories ↗](https://getlaminas.org/security/advisories)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/cache-security/","name":"Cache security"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/cache-security/avoid-web-poisoning/","name":"Avoid web cache poisoning"}}]}
```

---

---
title: Cache Deception Armor
description: Before learning about Cache Deception Armor, you should first understand how Web Cache Deception attacks work.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/cache-security/cache-deception-armor.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Deception Armor

Before learning about Cache Deception Armor, you should first understand how Web Cache Deception attacks work.

## Web Cache Deception attacks

Web Cache Deceptions attacks occur when an attacker tricks a user into opening a link in the format of `http://www.example.com/newsfeed/foo.jpg`, when `http://www.example.com/newsfeed` is the location of a dynamic script that returns different content for different users.

This scenario becomes problematic when your website is configured to be flexible about what kinds of paths it can handle. To be more specific, when requests to a path that do not exist, such as `/x/y/z` are treated as equivalent to requests to a parent path that does exist `/x`.

For example, an attacker could send a user a link to `http://www.example.com/newsfeed/foo.jpg` so that the user could be taken to their newsfeed. When the request passes through Cloudflare, the request would be cached because the path ends in `.jpg`. The attacker can then visit the same URL themselves, and their request will be served from Cloudflare's cache, exposing your user's sensitive content.

## Cache Deception Armor protects against attacks

You can protect users from Web Cache Deception attacks by [creating a cache rule](https://developers.cloudflare.com/cache/cache-security/cache-deception-armor/#enable-cache-deception-armor). With this rule, you can continue to cache static assets, but the rule will verify a URL's extension matches the returned `Content-Type`.

In the newsfeed example above, if `http://www.example.com/newsfeed` is a script that outputs a webpage, the `Content-Type` is `text/html`. On the other hand, `http://www.example.com/newsfeed/foo.jpg` is expected to have `image/jpeg` as `Content-Type`. When a mismatch that could result in a Web Cache Deception attack is found, Cloudflare does not cache the response.

### Exceptions

* If the returned `Content-Type` is `application/octet-stream`, the extension does not matter because that is typically a signal to instruct the browser to save the asset instead of to display it.
* Cloudflare allows `.jpg` to be served as `image/webp` or `.gif` as `video/webm` and other cases that we think are unlikely to be attacks.
* Keep in mind that Cache Deception Armor depends upon [Origin Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/). A `Cache-Control` header from the origin, or an [Edge Cache TTL Cache Rule](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl) may override the protection.

## Enable Cache Deception Armor

To enable Cache Deception Armor, you need to start by creating a [cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/). Follow the steps below for guidance:

1. In the Cloudflare dashboard, go to the **Cache Rules** page.  
[ Go to **Cache Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules)
2. Select **Create rule**.
3. Under **When incoming requests match**, define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-builder).
4. Under **Then**, in the **Cache eligibility** section, select **Eligible for cache**.
5. Add the **Cache Key** setting to the rule and turn on **Cache deception armor**.
6. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/cache-security/","name":"Cache security"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/cache-security/cache-deception-armor/","name":"Cache Deception Armor"}}]}
```

---

---
title: Cross-Origin Resource Sharing (CORS)
description: A cross-origin request is a request for website resources external to the origin. For example, a.example.com attempts to serve resources from b.secondexample.com. CORS instructs the browser to determine if a cross-origin request, such as an image or JavaScript from b.secondexample.com, is allowed by a.example.com. The browser does not load resources that are disallowed by CORS.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/cache-security/cors.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cross-Origin Resource Sharing (CORS)

A cross-origin request is a request for website resources external to the origin. For example, `a.example.com` attempts to serve resources from `b.secondexample.com`. CORS instructs the browser to determine if a cross-origin request, such as an image or JavaScript from `b.secondexample.com`, is allowed by `a.example.com`. The browser does not load resources that are disallowed by CORS.

Cloudflare supports CORS by:

* Identifying cached assets based on the `Host` Header, `Origin` Header, URL path, and query. This allows different resources to use the same `Host` header but different `Origin` headers.
* Passing `Access-Control-Allow-Origin` headers from the origin server to the browser.

The `Access-Control-Allow-Origin` header allows servers to specify rules for sharing their resources with external domains. When a server receives a request to access a resource, it responds with a value for the `Access-Control-Allow-Origin` header. `Access-Control-Allow-Origin` headers are often applied to [cacheable content](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/). A web server may respond with different `Access-Control` headers depending on the `Origin` header sent in the request.

## Add or change CORS headers at the origin server

If you add or change CORS configuration at your origin web server, purging the Cloudflare cache by URL does not update the CORS headers. Force Cloudflare to retrieve the new CORS headers via one of the following options:

* Change the filename or URL to bypass cache to instruct Cloudflare to retrieve the latest CORS headers.
* Use the [single-file purge API](https://developers.cloudflare.com/api/resources/cache/methods/purge/#purge-cached-content-by-url) to specify the appropriate CORS headers along with the purge request.
* Update the resource’s last-modified time at your origin web server. Then, complete a [full purge](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-everything/) to retrieve the latest version of your assets including updated CORS headers.

## Add or change CORS headers on Cloudflare

You can use one of following methods to set CORS headers using Cloudflare products:

* Use a [Worker](https://developers.cloudflare.com/workers/): Refer to [CORS header proxy](https://developers.cloudflare.com/workers/examples/cors-header-proxy/) for an example.
* Configure a [Snippet](https://developers.cloudflare.com/rules/snippets/): Refer to [Define CORS headers](https://developers.cloudflare.com/rules/snippets/examples/define-cors-headers/) for an example.
* Use [Transform Rules](https://developers.cloudflare.com/rules/transform/): Refer to [Add a wildcard CORS response header](https://developers.cloudflare.com/rules/transform/examples/add-cors-header/) for an example.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/cache-security/","name":"Cache security"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/cache-security/cors/","name":"Cross-Origin Resource Sharing (CORS)"}}]}
```

---

---
title: Head Requests and Set-Cookie Headers
description: In this page, we document how Cloudflare's cache system behaves in interaction with:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/cache-behavior.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Head Requests and Set-Cookie Headers

In this page, we document how Cloudflare's cache system behaves in interaction with:

* `HEAD` requests
* `Set-Cookie` response headers

## Interaction of `HEAD` requests with Cache

Cloudflare converts `HEAD` requests to `GET` requests for [cacheable requests](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions).

When you make a `HEAD` request for a cacheable resource and Cloudflare does not have that resource in the edge cache, a cache miss happens. Cloudflare will send a `GET` request to your origin, cache the full response and return the response headers only. Make sure the origin server is setup to handle `GET` requests, even if only `HEAD` requests are expected, so that compatibility with this behavior is ensured.

## Interaction of `Set-Cookie` response header with Cache

For non-cacheable requests, `Set-Cookie` is always preserved. For cacheable requests, there are three possible behaviors:

* `Set-Cookie` is returned from origin and the default cache level is used. If [origin cache control](https://developers.cloudflare.com/cache/concepts/cache-control/) is not enabled, Cloudflare removes the `Set-Cookie` and caches the asset. If origin cache control is enabled, Cloudflare does not cache the asset and preserves the `Set-Cookie`. A cache status of `BYPASS` is returned.
* `Set-Cookie` is returned from origin and the cache level is set to `Cache Everything` in Page Rules, or `Eligible for cache` in Cache Rules. In this case, Cloudflare preserves the `Set-Cookie` but does not cache the asset. A cache `MISS` will be returned every time.
* `Set-Cookie` is returned from origin, the cache level is set to `Cache Everything` in Page Rules, or `Eligible for cache` in Cache Rules, and edge cache TTL is explicitly set using either the "Ignore cache-control header and use this TTL" or "Status code TTL" setting. In this case, Cloudflare removes the `Set-Cookie` and the asset is cached.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/cache-behavior/","name":"Head Requests and Set-Cookie Headers"}}]}
```

---

---
title: Origin Cache Control
description: Origin Cache Control is a Cloudflare feature. When enabled on an Enterprise customer's website, it indicates that Cloudflare should strictly respect Cache-Control directives received from the origin server. Free, Pro and Business customers have this feature enabled by default.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/cache-control.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Cache Control

Origin Cache Control is a Cloudflare feature. When enabled on an Enterprise customer's website, it indicates that Cloudflare should strictly respect `Cache-Control` directives received from the origin server. Free, Pro and Business customers have this feature enabled by default.

`Cache-Control` directives in the HTTP response from your origin server provide specific [caching instructions ↗](https://datatracker.ietf.org/doc/html/rfc7234) to intermediary services like Cloudflare.

With the Origin Cache Control feature enabled, `Cache-Control` directives present in the origin server's response will be followed as specified. For example, if the response includes a `max-age` directive of 3,600 seconds, Cloudflare will cache the resource for that duration before checking the origin server again for updates.

Cloudflare's [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) allows users to either augment or override an origin server's `Cache-Control` headers or [default policies](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/) set by Cloudflare.

In the following sections, we will provide more details regarding:

* The most common `Cache-Control` directives.
* How to enable Origin Cache Control.
* How Origin Cache Control behaves with `Cache-Control` directives.
* How other Cloudflare products interact with `Cache-Control` directives.

## `Cache-control` directives

A `Cache-Control` header can include a number of directives, and the directive dictates who can cache a resource along with how long those resources can be cached before they must be updated.

Note

For more information about `Cache-Control` directives at origin servers, refer to the [Mozilla Cache-Control documentation ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control).

If multiple directives are passed together, each directive is separated by a comma. If the directive takes an argument, it follows the directive separated by an equal sign. For example: `max-age=86400`.

Directives can be broken down into four groups: [cacheability](https://developers.cloudflare.com/cache/concepts/cache-control/#cacheability), [expiration](https://developers.cloudflare.com/cache/concepts/cache-control/#expiration), [revalidation](https://developers.cloudflare.com/cache/concepts/cache-control/#revalidation), and [other](https://developers.cloudflare.com/cache/concepts/cache-control/#other).

### Cacheability

Cacheability refers to whether or not a resource should enter a cache, and the directives below indicate a resource's cacheability.

* `public` — Indicates any cache may store the response, even if the response is normally non-cacheable or cacheable only within a private cache.
* `private` — Indicates the response message is intended for a single user, such as a browser cache, and must not be stored by a shared cache like Cloudflare or a corporate proxy.
* `no-store` — Indicates any cache, such as a client or proxy cache, must not store any part of either the immediate request or response.

### Expiration

Expiration refers to how long a resource should remain in the cache, and the directives below affect how long a resource stays in the cache.

Note

Cloudflare respects whichever value is higher: the [Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/) in Cloudflare or the `max-age` header. You can also simultaneously specify a Cloudflare Edge Cache TTL different than a Browser's Cache TTL respectively via the `s-maxage` and `max-age` `Cache-Control` headers.

When using Origin Cache Control and setting `max-age=0`, Cloudflare prefers to cache and revalidate. With Origin Cache Control off and `max-age=0`, Cloudflare will bypass cache.

When setting `no-cache` with Origin Cache Control off, Cloudflare does not cache. When setting `no-cache` with Origin Cache Control on, Cloudflare caches and always revalidates.

* `max-age=seconds` — Indicates the response is stale after its age is greater than the specified number of seconds. Age is defined as the time in seconds since the asset was served from the origin server. The `seconds` argument is an unquoted integer.
* `s-maxage=seconds` — Indicates that in shared caches, the maximum age specified by this directive overrides the maximum age specified by either the `max-age` directive or the `Expires` header field. The `s-maxage` directive also implies the semantics of the proxy-revalidate response directive. Browsers ignore `s-maxage`.
* `no-cache` — Indicates the response cannot be used to satisfy a subsequent request without successful validation on the origin server. This allows an origin server to prevent a cache from using the origin to satisfy a request without contacting it, even by caches that have been configured to send stale responses.

Ensure the HTTP `Expires` header is set in your origin server to use Greenwich Mean Time (GMT) as stipulated in [RFC 2616 ↗](https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3 "3.3.1 Full Date").

### Revalidation

Revalidation determines how the cache should behave when a resource expires, and the directives below affect the revalidation behavior.

* `must-revalidate` — Indicates that once the resource is stale, a cache (client or proxy) must not use the response to satisfy subsequent requests without successful validation on the origin server.
* `proxy-revalidate` — Has the same meaning as the `must-revalidate` response directive except that it does not apply to private client caches.
* `stale-while-revalidate=<seconds>` — When present in an HTTP response, indicates caches may serve the response in which it appears after it becomes stale, up to the indicated number of seconds since the resource expired. If [Always Online](https://developers.cloudflare.com/cache/how-to/always-online/) is enabled, then the `stale-while-revalidate` and `stale-if-error` directives are ignored. This directive is not supported when using the Cache API methods `cache.match` or `cache.put`. For more information, refer to the [Workers documentation for Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/#methods).

Note

`stale-while-revalidate` is now fully asynchronous. The first request after expiry triggers revalidation in the background and immediately receives stale content with an UPDATING status instead of blocking. All requests during revalidation are served stale with an UPDATING status until the origin responds, after which they receive a HIT.

For more details, refer to [Revalidation](https://developers.cloudflare.com/cache/concepts/revalidation/#asynchronous-revalidation).

* `stale-if-error=<seconds>` — Indicates that when an error is encountered, a cached stale response may be used to satisfy the request, regardless of other freshness information. To avoid this behavior, include `stale-if-error=0` directive with the object returned from the origin. This directive is not supported when using the Cache API methods `cache.match` or `cache.put`. For more information, refer to the [Workers documentation for Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/#methods).

The `stale-if-error` directive is ignored if [Always Online](https://developers.cloudflare.com/cache/how-to/always-online/) is enabled or if an explicit in-protocol directive is passed. Examples of explicit in-protocol directives include a `no-store` or `no-cache cache` directive, a `must-revalidate` cache-response-directive, or an applicable `s-maxage` or `proxy-revalidate` cache-response-directive.

### Other

Additional directives that influence cache behavior are listed below.

* `no-transform` — Indicates that an intermediary — regardless of whether it implements a cache — must not transform the payload.
* `vary` — Cloudflare does not consider vary values in caching decisions. Nevertheless, vary values are respected when [Vary for images](https://developers.cloudflare.com/cache/advanced-configuration/vary-for-images/) is configured and when the vary header is [vary: accept-encoding](https://developers.cloudflare.com/speed/optimization/content/compression/).
* `immutable` — Indicates to clients the response body does not change over time. The resource, if unexpired, is unchanged on the server. The user should not send a conditional revalidation request, such as `If-None-Match` or `If-Modified-Since`, to check for updates, even when the user explicitly refreshes the page. This directive has no effect on public caches like Cloudflare, but does change browser behavior.

### Understand `no-store` and `no-cache` directives

There is often confusion between the directives `Cache-Control: no-store` and `Cache-Control: no-cache`, particularly regarding how they impact browser caching and features like the [Back-Forward Cache ↗](https://developer.mozilla.org/en-US/docs/Glossary/bfcache) (BFCache).

#### `no-store`

* Tells both browsers and intermediaries (like CDNs) not to store a copy of the response under any circumstance.
* The response is never written to disk or memory, which means the browser must fetch it again every time.
* In many browsers, `no-store` disables BFCache, because restoring a page from BFCache requires the browser to keep a copy of the page's memory state, which contradicts the “do not store” directive.
* This directive is used for highly sensitive or dynamic data (for example, banking apps, personal information, secure dashboards).

#### `no-cache`

* Allows storing of the response (in both browser and intermediate caches), but requires revalidation with the origin server before using it.
* This ensures the content is always up-to-date, while still potentially allowing BFCache or other forms of performance optimization.
* This directive is used for data that changes frequently but is not sensitive, and can be served faster if validated rather than re-downloaded.

For more information about how these directives behave when Origin Cache Control is enabled or disabled refer to the [Directives](https://developers.cloudflare.com/cache/concepts/cache-control/#directives) section.

## Enable Origin Cache Control

If you enable Origin Cache Control, Cloudflare will aim to strictly adhere to [RFC 7234 ↗](https://datatracker.ietf.org/doc/html/rfc7234). Enterprise customers have the ability to select if Cloudflare will adhere to this behavior, enabling or disabling Origin Cache Control for their websites through cache rules in the [dashboard](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#origin-cache-control-enterprise-only) or via [API](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#origin-cache-control-enterprise-only). Free, Pro, and Business customers have this option enabled by default and cannot disable it.

## Origin Cache Control behavior

The following section covers the directives and behavioral conditions associated with enabling or disabling Origin Cache Control.

### Directives

The table below lists directives and their behaviors when Origin Cache Control is disabled and when it is enabled.

| Directive               | Origin Cache Control Disabled Behavior          | Origin Cache Control Enabled Behavior                                                                                                        |
| ----------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| s-maxage=0              | Will not cache.                                 | Caches and always revalidates                                                                                                                |
| max-age=0               | Will not cache.                                 | Caches and always revalidates.                                                                                                               |
| no-cache                | Will not cache.                                 | Caches and always revalidates. Does not serve stale.                                                                                         |
| no-cache=<headers>      | Will not cache.                                 | Caches if headers mentioned in no-cache=<headers> do not exist. Always revalidates if any header mentioned in no-cache=<headers> is present. |
| Private=<headers>       | Will not cache.                                 | Does not cache <headers> values mentioned in Private=<headers> directive.                                                                    |
| must-revalidate         | Cache directive is ignored and stale is served. | Does not serve stale. Must revalidate for CDN and for browser.                                                                               |
| proxy-revalidate        | Cache directive is ignored and stale is served. | Does not serve stale. Must revalidate for CDN but not for browser.                                                                           |
| no-transform            | May (un)Gzip, Polish, email filter, etc.        | Does not transform body.                                                                                                                     |
| s-maxage=delta, delta>1 | Same as max-age.                                | Max-age and proxy-revalidate.                                                                                                                |
| immutable               | Not proxied downstream.                         | Proxied downstream. Browser facing, does not impact caching proxies.                                                                         |
| no-store                | Will not cache.                                 | Will not cache.                                                                                                                              |

### Conditions

Certain scenarios also affect Origin Cache Control behavior when it is enabled or disabled.

| Condition                                                              | Origin Cache Control disabled behavior                      | Origin Cache Control enabled behavior                        | |  Presence of Authorization header. | Content may be cached. | Content is cached only if must-revalidate, public, or s-maxage is also present. |
| ---------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------ | ---------------------- | ------------------------------------------------------------------------------- |
| Use of no-cache header.                                                | In logs, cacheStatus=miss.                                  | In logs, cacheStatus=bypass.                                 |                                      |                        |                                                                                 |
| Origin response has Set-Cookie header and default cache level is used. | Content may be cached with stripped set-cookie header.      | Content is not cached.                                       |                                      |                        |                                                                                 |
| Browser Cache TTL is set.                                              | Cache-Control returned to eyeball does not include private. | If origin returns private in Cache-Control then preserve it. |                                      |                        |                                                                                 |

Note

When the `Cloudflare-Cdn-Cache-Control` header is set, OCC is turned **on** (regardless of whether OCC is enabled or disabled). As a result, we apply our Authorization header logic (per [RFC 7234, Section 3.2 ↗](https://tools.ietf.org/html/rfc7234#section-3.2)) to allow only the `s-maxage`, `must-revalidate`, or `public` directives. If any other directive is present, we do not cache the asset and instead return `BYPASS`.

## Examples

Review the examples below to learn which directives to use with the `Cache-Control` header to control specific caching behavior.

Cache a static asset.

`Cache-Control: public, max-age=86400`

Ensure a secret asset is never cached.

`Cache-Control: no-store`

Cache assets on browsers but not on proxy cache.

`Cache-Control: private, max-age=3600`

Cache assets in client and proxy caches, but prefer revalidation when serve.

`Cache-Control: public, no-cache`

Cache assets in proxy caches but REQUIRE revalidation by the proxy when serve.

`Cache-Control: public, no-cache, proxy-revalidate` or `Cache-Control: public, s-maxage=0`

Cache assets in proxy caches, but REQUIRE revalidation by any cache when serve.

`Cache-Control: public, no-cache, must-revalidate`

Cache assets, but ensure the proxy does not modify it.

`Cache-Control: public, no-transform`

This configuration also disables transformation like gzip or brotli compression from our edge to your visitors if the original payload was served uncompressed.

Cache assets with revalidation, but allow stale responses if origin server is unreachable.

`Cache-Control: public, max-age=3600, stale-if-error=60`

With this configuration, Cloudflare attempts to revalidate the content with the origin server after it has been in cache for 3600 seconds (one hour). If the server returns an error instead of proper revalidation responses, Cloudflare continues serving the stale resource for a total of one minute beyond the expiration of the resource.

Cache assets for different amounts of time on Cloudflare and in visitor browsers.

`Cache-Control: public, max-age=7200, s-maxage=3600`

Cache an asset and serve while asset is being revalidated.

`Cache-Control: max-age=600, stale-while-revalidate=30`

This configuration indicates the asset is fresh for 600 seconds. The asset can be served stale for up to an additional 30 seconds while Cloudflare revalidates the asset with the origin in the background. For more information, refer to [Revalidation](https://developers.cloudflare.com/cache/concepts/revalidation/).

## Interaction with other Cloudflare features

In this section, we provide details regarding how other Cloudflare features interact with `Cache-Control` directives.

### Edge Cache TTL

[Edge Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#edge-cache-ttl) Cache Rules override `s-maxage` and disable revalidation directives if present. When Origin Cache Control is enabled at Cloudflare, the original `Cache-Control` header passes downstream from our edge even if Edge Cache TTL overrides are present. Otherwise, when Origin Cache Control is disabled at Cloudflare, Cloudflare overrides the Origin Cache Control.

### Browser Cache TTL

[Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#browser-cache-ttl) Cache Rules override `max-age` settings passed downstream from our edge, typically to your visitor's browsers.

### Polish

[Polish](https://developers.cloudflare.com/images/polish/) is disabled when the `no-transform` directive is present.

### Gzip and Other Compression

Compression is disabled when the `no-transform` directive is present. If the original asset fetched from the origin is compressed, it is served compressed to the visitor. If the original asset is uncompressed, compression is not applied.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/cache-control/","name":"Origin Cache Control"}}]}
```

---

---
title: Cloudflare cache responses
description: The CF-Cache-Status header output indicates whether a resource is cached or not. To investigate cache responses returned by this header, use services like Redbot, webpagetest.org, or a visual tool like Cloudflare Optics plugin.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/cache-responses.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloudflare cache responses

The `CF-Cache-Status` header output indicates whether a resource is cached or not. To investigate cache responses returned by this header, use services like [Redbot ↗](https://redbot.org/), [webpagetest.org ↗](http://www.webpagetest.org/), or a visual tool like [Cloudflare Optics plugin ↗](https://chromewebstore.google.com/detail/cloudflare-optics/mdjgbjnbdnhneejmmaabmccfehigbjbe).

`Age` response header

The `Age` response header is a header returned from cache that specifies the time in seconds that an asset has been in Cloudflare's cache. This value resets if the asset is revalidated, purged, or evicted and then re-cached.

The `Age` header is only present for responses served from the cache. It will not appear on a cache MISS, dynamic traffic, the first request that populates the lower tier HIT from tiered cache `CacheTieredFill=true` or any responses that did not originate from the cache (for example, responses generated by a Worker that bypassed the cache).

Below you can find a comprehensive breakdown of Cloudflare's cache response statuses.

## HIT

The resource was found in Cloudflare's cache.

## MISS

The resource was not found in Cloudflare's cache and was served from the origin web server.

## NONE/UNKNOWN

Cloudflare generated a response that denotes the asset is not eligible for caching. This may have happened because:

* A Worker generated a response without sending any subrequests. In this case, the response did not come from cache, so the cache status will be `none/unknown`.
* A Worker request made a subrequest (`fetch`). In this case, the subrequest will be logged with a cache status, while the main request will be logged with `none/unknown` status (the main request did not hit cache, since Workers sits in front of cache).
* A WAF custom rule was triggered to block a request. The response will come from the Cloudflare global network before it hits cache. Since there is no cache status, Cloudflare will log as `none/unknown`.
* A [redirect rule](https://developers.cloudflare.com/rules/url-forwarding/) or [Always Use HTTPS](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/) caused the global network to respond with a redirect to another asset/URL. This redirect response happens before the request reaches cache, so the cache status is `none/unknown`.

## EXPIRED

The resource was found in Cloudflare's cache but was expired and served from the origin web server.

## STALE

The resource was served from Cloudflare's cache but was expired. Cloudflare could not contact the origin web server to retrieve an updated resource.

## BYPASS

The origin web server instructed Cloudflare to bypass cache via a `Cache-Control` header set to `no-cache`, `private`, or `max-age=0` even though Cloudflare originally preferred to cache the asset. BYPASS is returned when enabling [Origin Cache-Control](https://developers.cloudflare.com/cache/concepts/cache-control/). Cloudflare also sets BYPASS when your origin web server sends cookies in the response header. If the Request to your origin web server includes an `Authorization` header, in some cases the response will also be BYPASS. Refer to [Conditions](https://developers.cloudflare.com/cache/concepts/cache-control/#conditions) in the Origin Cache-Control behavior section for more details.

## REVALIDATED

The origin confirmed the cached resource was unchanged via a conditional request (`If-Modified-Since` or `If-None-Match`), and the response is served from Cloudflare's cache. This status reflects the synchronous validation path — the request waits for the origin to respond before being served.

With [asynchronous stale-while-revalidate](https://developers.cloudflare.com/cache/concepts/revalidation/#asynchronous-revalidation), most revalidations now return `UPDATING` or `HIT` instead. `REVALIDATED` is seen in the following situations: `stale-while-revalidate` is not set; directives like `must-revalidate` or `no-cache` (with [Origin Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/) enabled) prevent stale content from being served; or the zone is an Enterprise zone that has not yet been migrated (refer to [Synchronous revalidation](https://developers.cloudflare.com/cache/concepts/revalidation/#synchronous-revalidation-legacy)).

## UPDATING

The resource was expired but served from Cloudflare's cache while the origin updates it in the background. `UPDATING` is the expected status during [asynchronous stale-while-revalidate](https://developers.cloudflare.com/cache/concepts/revalidation/#asynchronous-revalidation) revalidation — all requests during the revalidation window receive `UPDATING` or `HIT` rather than waiting for the origin.

## DYNAMIC

Cloudflare does not consider the asset eligible to cache and your Cloudflare settings do not explicitly instruct Cloudflare to cache the asset. Instead, the asset was requested from the origin web server. Use [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) to implement custom caching options.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/cache-responses/","name":"Cloudflare cache responses"}}]}
```

---

---
title: CDN-Cache-Control
description: CDN-Cache-Control is a response header field set on the origin to separately control the behavior of CDN caches from other intermediaries that might handle a response. You can set the CDN-Cache-Control or Cloudflare-CDN-Cache-Control response header using the same directives used with the Cache-Control.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/cdn-cache-control.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# CDN-Cache-Control

`CDN-Cache-Control` is a response header field set on the origin to separately control the behavior of CDN caches from other intermediaries that might handle a response. You can set the `CDN-Cache-Control` or `Cloudflare-CDN-Cache-Control` response header using the same directives used with the [Cache-Control](https://developers.cloudflare.com/cache/concepts/cache-control/).

## Header precedence

You have several options available to determine how `CDN-Cache-Control` directives interact with `Cache-Control` directives.

If a [Cache Response Rule](https://developers.cloudflare.com/cache/how-to/cache-response-rules/) sets `Cache-Control` directives using the `set_cache_control` action, those directives take precedence over any origin-set `Cloudflare-CDN-Cache-Control` and `CDN-Cache-Control` headers.

When no Cache Response Rule applies, an origin can:

* Return the `CDN-Cache-Control` response header which Cloudflare evaluates to make caching decisions. `Cache-Control`, if also returned by the origin, is proxied as is and does not affect caching decisions made by Cloudflare. Additionally, `CDN-Cache-Control` is proxied downstream in case there are other CDNs between Cloudflare and the browser.
* Return the `Cloudflare-CDN-Cache-Control` response header. This results in the same behavior as the origin returning `CDN-Cache-Control` except Cloudflare does not proxy `Cloudflare-CDN-Cache-Control` downstream because it’s a header only used to control Cloudflare. This option is beneficial if you want only Cloudflare to have a different caching behavior while all other downstream servers rely on `Cache-Control` or if you do not want Cloudflare to proxy the `CDN-Cache-Control` header downstream.
* Return both `Cloudflare-CDN-Cache-Control` and `CDN-Cache-Control` response headers. In this case, Cloudflare only looks at `Cloudflare-CDN-Cache-Control` when making caching decisions because it is the most specific version of `CDN-Cache-Control` and proxies `CDN-Cache-Control` downstream. Only forwarding `CDN-Cache-Control` in this situation is beneficial if you want Cloudflare to have a different caching behavior than other CDNs downstream.

Additionally, surrogates will not honor `Cache-Control` headers in the response from an origin. For example, if the `Surrogate-Control` header is present within the response, Cloudflare ignores any `Cache-Control` directives, even if the `Surrogate-Control` header does not contain directives.

## Interaction with other Cloudflare features

### Edge Cache TTL cache rule

The [Edge Cache TTL cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl) overrides the amount of time an asset is cached on the edge (Cloudflare data centers). This cache rule overrides directives in `Cloudflare-CDN-Cache-Control/CDN-Cache-Control` which manage how long an asset is cached on the edge. You can create this rule in the dashboard in **Caching** \> **Cache Rules**.

### Browser Cache TTL cache rule

The [Browser Cache TTL cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#browser-ttl) overrides the amount of time an asset is cached by browsers/servers downstream of Cloudflare. Browser Cache TTL only modifies the `Cache-Control` response header. This cache rule does not modify `Cloudflare-CDN-Cache-Control/CDN-Cache-Control` response headers.

### Other Origin Response Headers

The origin returns the `Expires` response header which specifies the amount of time before an object is considered stale to the browser. This response header does not affect the caching decision at Cloudflare when `Cloudflare-CDN-Cache-Control/CDN-Cache-Control` is in use.

### Cloudflare Default cache values

In situations where Cloudflare does not receive `Cloudflare-CDN-Cache-Control`, `CDN-Cache-Control`, or `Cache-Control` values, cacheable assets use the general [default values](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/).

## When to use CDN-Cache-Control

### Manage cached assets TTLs

Use `CDN-Cache-Control` when you want to manage cached asset’s TTLs separately for origin caches, CDN caches, and browser caches. The example below shows how you can manage your cached asset’s TTLs using origin-set response headers.

Headers:

* `Cache-Control: max-age=14400, s-maxage=84000`
* `Cloudflare-CDN-Cache-Control: max-age=24400`
* `CDN-Cache-Control: max-age=18000`

Cache behavior:

| Caches               | Cache TTL (seconds) | |  Origin Server Cache | 14400 |
| -------------------- | ------------------- | ---------------------- | ----- |
| Network Shared Cache | 84000               |                        |       |
| Cloudflare Edge      | 24400               |                        |       |
| Other CDNs           | 18000               |                        |       |
| Browser Cache        | 14400               |                        |       |

### Specify when to serve stale content

Use `CDN-Cache-Control` headers in conjunction with `Cache-Control` headers to specify when to serve stale content in the case of error or during revalidation. The example below shows how you might set your headers and directives to apply to CDNs when handling errors.

Headers:

* `Cache-Control: stale-if-error=400`
* `Cloudflare-CDN-Cache-Control: stale-if-error=60`
* `CDN-Cache-Control: stale-if-error=200`

Behavior in response to [5XX error](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/):

| Caches          | Stale served (seconds) in response to error | |  Origin Cache Layer/Network Cache/Browser Cache | 400 (if it assumes the directive applies) |
| --------------- | ------------------------------------------- | ------------------------------------------------- | ----------------------------------------- |
| Cloudflare Edge | 60                                          |                                                   |                                           |
| Other CDN       | 200                                         |                                                   |                                           |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/cdn-cache-control/","name":"CDN-Cache-Control"}}]}
```

---

---
title: Customize cache
description: Some possible combinations of origin web server settings and Cloudflare Cache Rules include:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/customize-cache.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Customize cache

Some possible combinations of origin web server settings and Cloudflare [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) include:

## Create a directory for static content at your origin web server

For example, create a `/static/` subdirectory at your origin web server and a Cache Everything Cache Rule matching the following expression:

* Using the Expression Builder: `Hostname contains "example.com" AND URI Path starts with "/static"`
* Using the Expression Editor: `(http.host contains "example.com" and starts_with(http.request.uri.path, "/static"))`

## Append a unique file extension to static pages

For example, create a `.shtml` file extension for resources at your origin web server and a Cache Everything Cache Rule matching the following expression:

* Using the Expression Builder: `Hostname contains "example.com" AND URI Path ends with ".shtml"`
* Using the Expression Editor: `(http.host contains "example.com" and ends_with(http.request.uri.path, ".shtml"))`

## Add a query string to a resource’s URL to mark the content as static

For example, add a `static=true` query string for resources at your origin web server and a Cache Everything Cache Rule matching the following expression:

* Using the Expression Builder: `Hostname contains "example.com" AND URI Query String contains "static=true"`
* Using the Expression Editor: `(http.host contains "example.com" and http.request.uri.query contains "static=true")`

Resources that match a Cache Everything Cache Rule are still not cached if the origin web server sends a Cache-Control header of `max-age=0`, `private`, `no-cache`, or an `Expires` header with an already expired date. Include the [Edge Cache TTL](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl) setting within the Cache Everything Cache Rule to additionally override the `Cache-Control` headers from the origin web server.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/customize-cache/","name":"Customize cache"}}]}
```

---

---
title: Default cache behavior
description: Cloudflare respects the origin web server’s cache headers in the following order unless an Edge Cache TTL cache rule overrides the headers. Refer to the Edge TTL section for details on default TTL behavior.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/default-cache-behavior.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Default cache behavior

Cloudflare respects the origin web server’s cache headers in the following order unless an [Edge Cache TTL cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl) overrides the headers. Refer to the [Edge TTL](https://developers.cloudflare.com/cache/how-to/configure-cache-status-code/#edge-ttl) section for details on default TTL behavior.

* Cloudflare **does not** cache the resource when:  
   * The `Cache-Control` header is set to `private`, `no-store`, `no-cache`, or `max-age=0`.  
   * The [Set-Cookie header](https://developers.cloudflare.com/cache/concepts/cache-behavior/#interaction-of-set-cookie-response-header-with-cache) exists.  
   * The HTTP request method is anything other than a `GET`.
* Cloudflare **does** cache the resource when:  
   * The `Cache-Control` header is set to `public` and `max-age` is greater than 0.  
   * The `Expires` header is set to a future date.

Note

Cloudflare does cache the resource even if there is no `Cache-Control` header based on [status codes](https://developers.cloudflare.com/cache/how-to/configure-cache-status-code/#edge-ttl).

Note

If both `max-age` and an `Expires` header are set, `max-age` will be used by Cloudflare.

When [Origin Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/) is enabled on an Enterprise customer’s website, it indicates that Cloudflare should strictly respect `Cache-Control` directives received from the origin server. Free, Pro and Business customers have this feature enabled by default. For a list of directives and behaviors when Origin Cache-Control is enabled or disabled, refer to [Cache-Control directives](https://developers.cloudflare.com/cache/concepts/cache-control/#cache-control-directives).

## Client side range requests

Clients can send range requests to be served from the cache using the `Range` header. Note that:

* If the origin response includes a `Content-Length` header, then the specified byte range will be returned with an [HTTP 206](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/2xx-success/#206-partial-content) response.
* If the origin response does not include the `Content-Length` header, the cache will return the full content with an HTTP 200 response.

## Request collapsing

When multiple requests arrive simultaneously at a single Cloudflare data center for the same asset that is not in cache (a cache miss), Cloudflare uses a cache lock to avoid sending duplicate requests to your origin. Only the first request is forwarded to the origin to fetch the asset. The remaining requests wait for the first request to complete, after which the response is [streamed ↗](https://blog.cloudflare.com/introducing-concurrent-streaming-acceleration/) to all waiting requests.

The cache lock ensures that Cloudflare only sends one request at a time to the origin for a given asset from a single location in Cloudflare's network, preventing the origin from receiving excessive traffic.

## Default cached file extensions

Cloudflare only caches based on file extension and not by MIME type. The Cloudflare CDN does not cache HTML or JSON by default. Additionally, by default Cloudflare caches a website's robots.txt.

| 7Z    | CSV  | GIF  | MIDI | PNG  | TIF   | ZIP |
| ----- | ---- | ---- | ---- | ---- | ----- | --- |
| AVI   | DOC  | GZ   | MKV  | PPT  | TIFF  | ZST |
| AVIF  | DOCX | ICO  | MP3  | PPTX | TTF   |     |
| APK   | DMG  | ISO  | MP4  | PS   | WEBM  |     |
| BIN   | EJS  | JAR  | OGG  | RAR  | WEBP  |     |
| BMP   | EOT  | JPG  | OTF  | SVG  | WOFF  |     |
| BZ2   | EPS  | JPEG | PDF  | SVGZ | WOFF2 |     |
| CLASS | EXE  | JS   | PICT | SWF  | XLS   |     |
| CSS   | FLAC | MID  | PLS  | TAR  | XLSX  |     |

To cache additional content, refer to [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) to create a rule to cache everything.

## Edge TTL

By default, Cloudflare caches certain HTTP response codes with the following Edge Cache TTL when a `cache-control` directive or `expires` response header are not present.

| HTTP status code | Default TTL |
| ---------------- | ----------- |
| 200, 206, 301    | 120m        |
| 302, 303         | 20m         |
| 404, 410         | 3m          |

All other status codes are not cached by default.

## Customization options and limits

Cloudflare’s CDN provides several cache customization options:

* Caching behavior for individual URLs via [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
[ Go to **Cache Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules) 
* Customize caching with [Cloudflare Workers](https://developers.cloudflare.com/workers/reference/how-the-cache-works/)
* Adjust caching level, cache TTL, and more in the Caching page in the Cloudflare dashboard:
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration) 

### Upload limits

| Free            | Pro    | Business | Enterprise |         |
| --------------- | ------ | -------- | ---------- | ------- |
| Availability    | Yes    | Yes      | Yes        | Yes     |
| Max upload size | 100 MB | 100 MB   | 200 MB     | 500+ MB |

Customers can reduce the **Maximum Upload Size** from the zone's **Network** page.

If you require a larger upload, you can group requests into smaller chunks, upload the full resource through an [unproxied (grey-clouded) DNS record](https://developers.cloudflare.com/dns/proxy-status/) or [upgrade your plan](https://developers.cloudflare.com/billing/change-plan/).

### Cacheable size limits

Cloudflare cacheable file limits:

* Free, Pro and Business customers have a limit of 512 MB.
* For Enterprise customers the default maximum cacheable file size is 5 GB. Contact your account team to request a limit increase.

## When does Cloudflare cache successfully?

The connection status between visitors and Cloudflare can vary, affecting whether Cloudflare caches the content or not. If Cloudflare has already established a connection to the origin and started fetching the content, it will continue to retrieve and cache the entire content, even if the visitor disconnects midway. However, if a visitor disconnects before the origin responds to Cloudflare's request, no content will have been fetched yet, so Cloudflare will not start caching the content.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/default-cache-behavior/","name":"Default cache behavior"}}]}
```

---

---
title: Retention vs Freshness (TTL)
description: In the context of Cloudflare CDN (Content Delivery Network), retention and freshness refer to two separate but related concepts. For an object in cache, freshness is how long it should be considered valid without consulting its source, while retention refers to how long it stays in cache before being removed.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/retention-vs-freshness.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Retention vs Freshness (TTL)

In the context of Cloudflare CDN (Content Delivery Network), retention and freshness refer to two separate but related concepts. For an object in cache, freshness is how long it should be considered valid without consulting its source, while retention refers to how long it stays in cache before being removed.

## Retention

When a file or resource is requested from a website, Cloudflare caches it to avoid having to ask the origin server for it again the next time it is requested, reducing latency and improving delivery speed. But if an object in cache does not get requested again, eventually it will be removed to make room for newer, more popular objects. This process is called eviction and is a standard part of cache management. When the cache wants to store a new object but does not have room, it uses an algorithm called Least Recently Used, or LRU, to nominate an object to evict and replace it with the new one. An object’s cache retention period refers to the duration the object is stored in Cloudflare’s cache before being evicted. It is worth noting that an object’s retention period is a function of its relative popularity and the size of Cloudflare’s caches, and therefore is not configurable.

## Freshness (TTL)

The time window that an object should be considered safe for a cache to use is dictated by its freshness, also known as Time to Live (TTL). If an object has a TTL of five minutes that means that, starting from the moment the cache first receives the object, for the next five minutes the cache can use that object without checking with the origin again. After five minutes have passed, if Cloudflare gets another request for that object, we cannot use what is stored in the cache without first checking the origin to see if the object is still valid. Those first five minutes in this object’s case are its freshness period. There are a few ways to configure TTLs for resources served through Cloudflare’s Content Delivery Network:

* Include [Origin Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/) or [CDN Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/) directives, like `max-age` or `s-maxage`, in the origin cache-control response header.
* Use [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) or [Workers](https://developers.cloudflare.com/cache/interaction-cloudflare-products/workers/).

If an object in cache is no longer fresh, Cloudflare revalidates it with the origin. When [stale-while-revalidate](https://developers.cloudflare.com/cache/concepts/cache-control/#revalidation) is set, revalidation happens asynchronously at expiry — visitors continue to be served from cache while Cloudflare fetches a fresh copy in the background. Without this directive, incoming requests wait for the origin to respond before receiving content. The origin can either confirm the cached object is still valid (refreshing its TTL) or return a new version to replace it. Refer to [Revalidation](https://developers.cloudflare.com/cache/concepts/revalidation/) for details.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/retention-vs-freshness/","name":"Retention vs Freshness (TTL)"}}]}
```

---

---
title: Revalidation
description: When a cached asset expires, Cloudflare uses the stale-while-revalidate directive in Cache-Control to determine whether it can continue serving the stale asset while fetching a fresh copy from the origin. If the directive is present and the asset is within the allowed staleness window, Cloudflare serves the expired content to visitors and revalidates in the background. By using headers like If-Modified-Since and ETag, Cloudflare validates content without fully re-fetching it, reducing origin traffic.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/concepts/revalidation.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Revalidation

## Stale-while-revalidate

When a cached asset expires, Cloudflare uses the [stale-while-revalidate](https://developers.cloudflare.com/cache/concepts/cache-control/#revalidation) directive in `Cache-Control` to determine whether it can continue serving the stale asset while fetching a fresh copy from the origin. If the directive is present and the asset is within the allowed staleness window, Cloudflare serves the expired content to visitors and revalidates in the background. By using headers like `If-Modified-Since` and `ETag`, Cloudflare validates content without fully re-fetching it, reducing origin traffic.

Note

Asynchronous `stale-while-revalidate` is live for all Free, Pro, and Business zones. Enterprise zones are actively being migrated. The previous synchronous behavior is described in [Synchronous revalidation](#synchronous-revalidation-legacy).

## Asynchronous revalidation

Revalidation is fully asynchronous. When a cached asset expires and `stale-while-revalidate` is set, the first request that arrives after expiry triggers revalidation in the background. That request immediately receives stale content with an [UPDATING](https://developers.cloudflare.com/cache/concepts/cache-responses/#updating) status instead of blocking until the origin responds. All following requests also receive stale content with an `UPDATING` status until the origin responds. Once revalidation completes, subsequent requests receive fresh content with a [HIT](https://developers.cloudflare.com/cache/concepts/cache-responses/#hit) status.

If the stale content is still valid, Cloudflare sets a new TTL. If the content has changed, the origin provides fresh content to replace the old.

## Synchronous revalidation (legacy)

Note

Synchronous revalidation refers to a previous implementation that is only available to a subset of Enterprise zones that have not been migrated yet. All other zones use [asynchronous revalidation](#asynchronous-revalidation).

With synchronous revalidation (a legacy implementation), `stale-while-revalidate` blocks on the first request that arrives after a cached asset expired. That first request is held until the origin responds, and is served with a [MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) or [REVALIDATED](https://developers.cloudflare.com/cache/concepts/cache-responses/#revalidated) status. Any other requests that arrive during this time for the same asset in the same cache location are served stale with the [UPDATING](https://developers.cloudflare.com/cache/concepts/cache-responses/#updating) status.

For example, if 1,000 requests arrive simultaneously for an expired asset in this previous implementation, one request goes to the origin while the other 999 are served stale from cache. The first visitor experiences higher latency because they have to wait for the origin round-trip.

On the other hand, with [asynchronous revalidation](#asynchronous-revalidation) all 1,000 requests are served from cache immediately and no visitor is blocked.

## Controlling stale behavior

Cloudflare only serves stale content during revalidation if your origin includes the `stale-while-revalidate` directive in its `Cache-Control` header. Without this directive, visitors wait for the origin to respond before receiving content.

If your origin sets `stale-while-revalidate` but you want to override it, you can disable stale serving through the [Serve stale content while revalidating](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#serve-stale-content-while-revalidating) setting in Cache Rules. Directives like `must-revalidate` and `no-cache` also prevent stale content from being served when [Origin Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/#enable-origin-cache-control) is enabled. For all available options, refer to [Cache-Control directives](https://developers.cloudflare.com/cache/concepts/cache-control/#cache-control-directives).

## Smart revalidation towards users

When both [Last-Modified ↗](https://datatracker.ietf.org/doc/html/rfc7232?cf%5Fhistory%5Fstate=%7B%22guid%22%3A%22C255D9FF78CD46CDA4F76812EA68C350%22%2C%22historyId%22%3A15%2C%22targetId%22%3A%226C8153BAEF7BC0C5A331E28F8BCF1ABA%22%7D#section-2.2) and [Etag ↗](https://datatracker.ietf.org/doc/html/rfc7232?cf%5Fhistory%5Fstate=%7B%22guid%22%3A%22C255D9FF78CD46CDA4F76812EA68C350%22%2C%22historyId%22%3A13%2C%22targetId%22%3A%226C8153BAEF7BC0C5A331E28F8BCF1ABA%22%7D#section-2.3) headers are absent from the origin server response, Smart Edge Revalidation will use the time the object was cached on Cloudflare's global network as the `Last-Modified` header value. When a browser sends a revalidation request to Cloudflare using `If-Modified-Since` or `If-None-Match`, our global network can answer those revalidation questions using the `Last-Modified` header generated from Smart Edge Revalidation. In this way, our global network can ensure efficient revalidation even if the headers are not sent from the origin.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/concepts/","name":"Concepts"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/concepts/revalidation/","name":"Revalidation"}}]}
```

---

---
title: Glossary
description: Review the definitions for terms used across Cloudflare's Cache documentation.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/glossary.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Glossary

Review the definitions for terms used across Cloudflare's Cache documentation.

| Term                                                     | Definition                                                                                                                                                                                                                                                                                                           |
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cache                                                    | A temporary storage area where frequently accessed data is stored for quick retrieval.                                                                                                                                                                                                                               |
| cache hit                                                | When a requested piece of content is found in the cache, reducing the need to fetch it from the origin server.                                                                                                                                                                                                       |
| cache lock                                               | Cache lock (or mutex) is a mechanism employed by CDN data centers, comprising numerous servers, to prevent the overloading of origin servers. This mechanism ensures that only one server can request a specific file from the origin at any given time, facilitating efficient coordination among the servers.      |
| cache miss                                               | When a requested piece of content is not found in the cache, requiring the server to fetch it from the origin server.                                                                                                                                                                                                |
| cached bandwidth (cached egress bandwidth)               | The amount of bandwidth served from Cloudflare without hitting the origin server. Cached bandwidth is the sum of all EdgeResponseBytes where CacheCacheStatus equals hit, stale, updating, ignored, or revalidated.                                                                                                  |
| cached requests                                          | The number of requests served from Cloudflare without having to hit the origin server. Cached requests are the sum of all requests where CacheCacheStatus equals hit, stale, updating, ignored. This does not include revalidated since the request had to be sent to the origin server.                             |
| caching                                                  | The process of storing copies of files or data in a cache to accelerate future requests.                                                                                                                                                                                                                             |
| dynamic content                                          | Dynamic content refers to website content that changes based on factors specific to the user such as time of visit, location, and device. News websites or social media are examples of this type of content. For this type of website, content has to be fetched from the origin server every time it is requested. |
| edge server                                              | A server located at the edge of a network, typically within a CDN, that serves content to end-users.                                                                                                                                                                                                                 |
| origin bandwidth (origin egress bandwidth)               | The amount of data transferred from the origin server to Cloudflare within a certain period of time. Origin bandwidth is the sum of all EdgeResponseBytes where OriginResponseStatus does not equal 0.                                                                                                               |
| origin server                                            | The original server where the web content is hosted before it is distributed to edge servers in a CDN.                                                                                                                                                                                                               |
| purge                                                    | The process of removing outdated content from the cache to make room for updated content and ensure the delivery of the latest content.                                                                                                                                                                              |
| saved bandwidth (saved egress bandwidth)                 | The percentage of bandwidth saved by caching on the Cloudflare network.                                                                                                                                                                                                                                              |
| static content                                           | Static content, like images, stylesheets, and JavaScript, remains the same for all users. It can be directly served from the cache without fetching from the origin server because it does not change without manual intervention.                                                                                   |
| time-to-live (TTL)                                       | The duration for which a cached copy of a resource is considered valid before it needs to be refreshed or revalidated.                                                                                                                                                                                               |
| total bandwidth (total egress bandwidth, edge bandwidth) | Total bandwidth is the amount of data transferred from Cloudflare to end users within a certain period of time. Total bandwidth equals the sum of all EdgeResponseBytes for a certain period of time.                                                                                                                |
| uncached bandwidth (uncached egress bandwidth)           | Uncached bandwidth is the amount of bandwidth that is not cached and therefore is served from the origin. Uncached bandwidth is the sum of all EdgeResponseBytes where CacheCacheStatus does not equal hit, stale, updating, ignored, or revalidated.                                                                |
| uncached requests                                        | Uncached requests are requests that are not cached and therefore are served from the origin server. Uncached requests are the sum of all requests where CacheCacheStatus does not equal to hit, stale, updating, or ignored.                                                                                         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/glossary/","name":"Glossary"}}]}
```

---

---
title: Always Online
description: Cloudflare’s Always Online feature is now integrated with the Internet Archive so that visitors can access a portion of your website even when your origin server is unreachable and a Cloudflare-cached version is unavailable. When your origin is unreachable, Always Online checks Cloudflare’s cache for a stale or expired version of your website. If a version does not exist, Cloudflare goes to the Internet Archive to fetch and serve static portions of your website.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/always-online.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Always Online

Cloudflare’s Always Online feature is now integrated with the [Internet Archive ↗](https://archive.org/) so that visitors can access a portion of your website even when your origin server is unreachable and a Cloudflare-cached version is unavailable. When your origin is unreachable, Always Online checks Cloudflare’s cache for a stale or expired version of your website. If a version does not exist, Cloudflare goes to the Internet Archive to fetch and serve static portions of your website.

When you enable Always Online with Internet Archive integration, Cloudflare shares your hostname and popular URL paths with the archive so that the Internet Archive’s crawler stores the pages you want archived. When submitting targets to the crawler, Cloudflare identifies the most popular URLs found among GET requests that returned a 200 HTTP status code in the previous five hours.

Note that Cloudflare does not save a copy of every page of your website, and it cannot serve dynamic content while your origin is offline. If the requested page is not in the Internet Archive's Wayback Machine, the visitor sees the actual error page caused by the offline origin web server.

When the Internet Archive integration is enabled, Cloudflare tells the Internet Archive what pages to crawl and how often. The pages to crawl, as previously mentioned, are the most popular URLs that were successfully visited in the last five hours. The crawling intervals, to ensure stability of service, are limited by Cloudflare. Limits vary according to your Cloudflare plan.

## Availability

| Free           | Pro           | Business      | Enterprise   |              |
| -------------- | ------------- | ------------- | ------------ | ------------ |
| Availability   | Yes           | Yes           | Yes          | Yes          |
| Crawl interval | Every 30 days | Every 15 days | Every 5 days | Every 5 days |

## Visitor Experience

When Always Online with Internet Archive integration is enabled, visitors see a banner at the top of the webpage explaining they are visiting an archived version of the website. Visitors can select the Refresh button to check whether the origin has recovered and fresh content is available.

When a visitor requests content for an offline website, Cloudflare returns an HTTP response status code in the range [520–527](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-520/), depending on the issue. These status codes indicate that the origin is unreachable.

When the Internet Archive integration is enabled, Cloudflare checks the archive and serves the most recently archived version of the page.

Visitors who interact with dynamic parts of a website, such as a shopping cart or comment box, will see an error page caused by the offline origin web server.

## Enable Always Online

Here is how to enable Always Online in the dashboard:

1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Choose the domain that will use Always Online with Internet Archive integration.
3. Under **Always Online**, set the toggle to **On**.

Note

When turning on Always Online, you are also enabling the Internet Archive integration.

Refer to [Always Online](https://developers.cloudflare.com/cache/troubleshooting/always-online/) for best practices, limitations, and FAQs.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/always-online/","name":"Always Online"}}]}
```

---

---
title: Cache keys
description: A Cache Key is an identifier that Cloudflare uses for a file in our cache, and the Cache Key Template defines the identifier for a given HTTP request.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-keys.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache keys

A Cache Key is an identifier that Cloudflare uses for a file in our cache, and the Cache Key Template defines the identifier for a given HTTP request.

A default cache key includes:

1. Full URL:  
   * scheme - could be HTTP or HTTPS.  
   * host - for example, `www.cloudflare.com`  
   * URI with query string - for example, `/logo.jpg?utm_source=newsletter`
2. Origin header sent by client (for CORS support).
3. `x-http-method-override`, `x-http-method`, and `x-method-override` headers.
4. `x-forwarded-host`, `x-host`, `x-forwarded-scheme` (unless http or https), `x-original-url`, `x-rewrite-url`, and `forwarded` headers.

## Create custom cache keys

Custom cache keys let you precisely set the cacheability setting for any resource. They provide the benefit of more control, though they may reduce your cache hit rate and result in cache sharding:

1. In the Cloudflare dashboard, go to the **Cache Rules** page.  
[ Go to **Cache Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules)
2. Select **Create rule**.
3. Under **When incoming requests match**, define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-builder).
4. Under **Then**, in the **Cache eligibility** section, select **Eligible for cache**.
5. Add the **Cache Key** setting to the rule and select the appropriate **Query String** setting.
6. You can also select settings for **Headers**, **Cookie**, **Host**, and **User**.
7. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.

Note

When [URL normalization](https://developers.cloudflare.com/rules/normalization/) is enabled, we recommend also enabling [Normalize URLs to origin](https://developers.cloudflare.com/rules/normalization/manage/), especially if you are setting custom cache keys or using cache by device type, which also modifies the cache key. This helps ensure the URL in the cache key matches the URL sent to the origin, preventing cache poisoning and ensuring consistent behavior.

## Cache Key Template

There are a couple of common reasons to change the Cache Key Template. You might change the Cache Key Template to:

* Fragment the cache so one URL is stored in multiple files. For example, to store different files based on a specific query string in the URL.
* Consolidate the cache so different HTTP requests are stored in the same file. For example, to remove the Origin header added to Cloudflare Cache Keys by default.

### Impact of SSL settings on Cache behavior

Cloudflare's `$scheme` variable plays a key role in caching behavior, but its meaning varies depending on the cache key type:

* **Default Cache Key**: `$scheme` refers to the **origin scheme** — the protocol Cloudflare uses to connect to your origin server (HTTP or HTTPS). In this configuration, changes to your SSL settings (for example, switching from Flexible to Full) alter the origin scheme. Because the cache key includes the origin scheme, such changes trigger a cache bust, requiring Cloudflare to fetch content again from the origin.
* **Custom Cache Key**: `$scheme` refers to the **visitor's scheme** — the protocol used by the client making the request to Cloudflare. In this case, SSL setting changes do not impact the cache key unless the origin scheme is explicitly included in your custom configuration.

For example, with Flexible SSL, Cloudflare always connects to the origin over HTTP, regardless of whether the visitor uses HTTP or HTTPS. This results in the same cache key for both protocols under the default configuration.

Be aware that changes in the SSL setting can lead to cache invalidation when using the default cache key:

* Switching from **Off** to **Full**, **Full (strict)**, or **Strict** updates the origin scheme from HTTP to HTTPS, resulting in a cache bust.
* Moving from **Flexible** to **Full**, **Full (strict)**, or **Strict** similarly changes the origin scheme to HTTPS and causes a cache bust.

Understanding how `$scheme` interacts with your caching configuration is essential when modifying SSL modes to avoid unexpected cache behavior.

### Cache Level: Ignore Query String

A [Cache Level](https://developers.cloudflare.com/cache/how-to/set-caching-levels/) of Ignore Query String creates a Cache Key that includes all the elements in the default cache key, except for the query string in the URI that is no longer included. For instance, a request for `http://example.com/file.jpg?something=123` and a request for `http://example.com/file.jpg?something=789` will have the same cache key, in this case.

## Cache Key Settings

The following fields control the Cache Key Template.

### Query String

The query string controls which URL query string parameters go into the Cache Key. You can `include` specific query string parameters or `exclude` them using the respective fields. When you include a query string parameter, the `value` of the query string parameter is used in the Cache Key.

#### Example

If you include the query string foo in a URL like `https://www.example.com/?foo=bar`, then bar appears in the Cache Key. Exactly one of `include` or `exclude` is expected.

#### Usage notes

* To include all query string parameters (the default behavior), use include: `"\*"`
* To ignore query strings, use exclude: `"\*"`
* To include most query string parameters but exclude a few, use the exclude field which assumes the other query string parameters are included.

### Headers

Headers control which headers go into the Cache Key. Similar to Query String, you can include specific headers or exclude default headers.

When you include a header, the header value is included in the Cache Key. For example, if an HTTP request contains an HTTP header like `X-Auth-API-key: 12345`, and you include the `X-Auth-API-Key header` in your Cache Key Template, then `12345` appears in the Cache Key.

In the **Include headers and selected values** section, you can add header names and their values to the cache key. For custom headers, values are optional, but for the following restricted headers, you must include one to 10 specific values:

* `accept`
* `accept-charset`
* `accept-encoding`
* `accept-datetime`
* `accept-language`
* `referer`
* `user-agent`

To check for the presence of a header without including its actual value, use the **Check presence of** option.

Currently, you can only exclude the `Origin` header. The `Origin` header is always included unless explicitly excluded. Including the [Origin header ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Origin) in the Cache Key is important to enforce [CORS ↗](https://developer.mozilla.org/en-US/docs/Glossary/CORS).

Additionally, you cannot include the following headers:

* Headers that re-implement cache or proxy features  
   * `connection`  
   * `content-length`  
   * `cache-control`  
   * `if-match`  
   * `if-modified-since`  
   * `if-none-match`  
   * `if-unmodified-since`  
   * `range`  
   * `upgrade`
* Headers that are covered by other Cache Key features  
   * `cookie`  
   * `host`
* Headers that are specific to Cloudflare and prefixed with `cf-`, for example, `cf-ray`
* Headers that are already included in the custom Cache Key template, for example, `origin`

### Host

Host determines which host header to include in the Cache Key.

* If `Use original host` (`resolved: false` in the API), Cloudflare includes the `Host` header in the HTTP request sent to the origin.
* If `Resolved host` (`resolved: true` in the API), Cloudflare includes the `Host` header that was resolved to get the `origin IP` for the request. The `Host` header may be different from the header actually sent if it has been changed with an [Origin Rule](https://developers.cloudflare.com/rules/origin-rules/features/#dns-record).

### Cookie

Like `query_string` or `header`, `cookie` controls which cookies appear in the Cache Key. You can either include the cookie value or check for the presence of a particular cookie.

#### Usage notes

You cannot include cookies specific to Cloudflare. Cloudflare cookies are prefixed with `__cf`, for example, `__cflb`

### User features

User feature fields add features about the end-user (client) into the Cache Key.

* `device_type` classifies a request as `mobile`, `desktop`, or `tablet` based on the User Agent
* `geo` includes the client’s country, derived from the IP address
* `lang` includes the first language code contained in the `Accept-Language` header sent by the client

## Availability

Cache keys options availability varies according to your plan.

| Free                  | Pro | Business | Enterprise |     |
| --------------------- | --- | -------- | ---------- | --- |
| Cache deception armor | Yes | Yes      | Yes        | Yes |
| Cache by device type  | Yes | Yes      | Yes        | Yes |
| Ignore query string   | Yes | Yes      | Yes        | Yes |
| Sort query string     | Yes | Yes      | Yes        | Yes |
| Query string          | No  | No       | No         | Yes |
| Headers               | No  | No       | No         | Yes |
| Cookie                | No  | No       | No         | Yes |
| Host                  | No  | No       | No         | Yes |
| User features         | No  | No       | No         | Yes |

## Troubleshooting

You can use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to find which Cache Key settings were applied to your request. When you send a request through the Trace tool, if the request was served from cache, it will show a cache hit in the **Cache Paremeters** section. Then select **View paremeter detail** to see exactly which Cache Key properties were used.

## Limitations

The [Prefetch](https://developers.cloudflare.com/speed/optimization/content/prefetch-urls/) feature is not compatible with the [Custom Cache Keys](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/custom-cache-key/). With [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/), the custom cache key is used to cache all assets. However, Prefetch always uses the default cache key. This results in a key mismatch.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-keys/","name":"Cache keys"}}]}
```

---

---
title: Cache Response Rules
description: Cache Response Rules allow you to configure cache settings based on request and response attributes. These rules execute prior to caching in the http_response_cache_settings phase, which runs after Cloudflare receives the origin response.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-response-rules/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Response Rules

Cache Response Rules allow you to configure cache settings based on request and response attributes. These rules execute prior to caching in the `http_response_cache_settings` phase, which runs after Cloudflare receives the origin response.

With Cache Response Rules you can:

* Modify `Cache-Control` directives sent by your origin.
* Modify cache tags on responses for targeted [cache purging](https://developers.cloudflare.com/cache/how-to/purge-cache/).
* Strip headers (`ETag`, `Set-Cookie`, `Last-Modified`) from origin responses before caching.

Cache Response Rules apply to both cached and non-cached (dynamic) responses from the origin. For example, you can strip Set-Cookie headers from responses that are not eligible for caching.

Cache Response Rules can be created in the [dashboard](https://developers.cloudflare.com/cache/how-to/cache-response-rules/create-dashboard/), via [API](https://developers.cloudflare.com/cache/how-to/cache-response-rules/create-api/), or [Terraform](https://developers.cloudflare.com/cache/how-to/cache-response-rules/terraform-example/).

Note

Cache Response Rules require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## Availability

The following table describes Cache Response Rules availability per plan.

| Free            | Pro | Business | Enterprise |     |
| --------------- | --- | -------- | ---------- | --- |
| Availability    | Yes | Yes      | Yes        | Yes |
| Number of rules | 10  | 25       | 50         | 300 |

## Troubleshooting

When troubleshooting Cache Response Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

## Relationship with Cache Rules

Cache Response Rules operate on the origin response, while [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) operate on the incoming request. When settings from both rule types conflict, Cache Response Rules take precedence.

Key differences:

* **Cache eligibility**: Cache Rules remain the only mechanism to decide whether content is eligible for caching. However, Cache Response Rules can make a cacheable asset non-cacheable by setting the `no-store` directive using the `set_cache_control` action.
* **Origin Cache Control (OCC)**: If any rule in the `http_response_cache_settings` phase matches, Cloudflare defaults to Origin Cache Control behavior (`origin_cache_control = true`).
* **CDN-Cache-Control precedence**: `Cache-Control` directives set by Cache Response Rules take precedence over origin-set `Cloudflare-CDN-Cache-Control` and `CDN-Cache-Control` headers. For more information, refer to [CDN-Cache-Control header precedence](https://developers.cloudflare.com/cache/concepts/cdn-cache-control/#header-precedence).
* **Stacking**: Cache Response Rules stack the same way as Cache Rules. When multiple rules specify the same setting, the last matching rule wins.

### Example: OCC precedence over Edge TTL

Consider the following scenario:

1. A Cache Rule sets **Edge TTL** to `override_origin` with a value of `7200` seconds (2 hours).
2. A Cache Response Rule uses `set_cache_control` to set `s-maxage` to `3600` seconds (1 hour) with `cloudflare_only` enabled.
3. The origin responds with `Cache-Control: s-maxage=600`.

In this case, the Cache Response Rule takes precedence. Cloudflare caches the asset for `3600` seconds (1 hour) based on the `s-maxage` directive set by the Cache Response Rule, while visitors still receive the original `s-maxage=600` from the origin because `cloudflare_only` is enabled.

## Notes

* If you strip last modified then Smart Edge Revalidation will be turned off.
* Cache Response Rules ignore HTTP Response 1xx as it is treated as informational responses.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-response-rules/","name":"Cache Response Rules"}}]}
```

---

---
title: Create a rule via API
description: Use the Rulesets API to create a Cache Response Rule via API. To configure the Cloudflare API, refer to the API documentation.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-response-rules/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create a Cache Response Rule via API. To configure the Cloudflare API, refer to the [API documentation](https://developers.cloudflare.com/fundamentals/api/get-started/).

## Basic rule settings

When creating a Cache Response Rule via API, make sure you:

* Set the rule action to one of the [available actions](https://developers.cloudflare.com/cache/how-to/cache-response-rules/settings/#available-actions).
* Define the parameters in the `action_parameters` field according to the [settings](https://developers.cloudflare.com/cache/how-to/cache-response-rules/settings/) you wish to configure for matching responses.
* Deploy the rule to the `http_response_cache_settings` phase entry point ruleset.

## Procedure

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) method to check if a ruleset already exists for the `http_response_cache_settings` phase.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * kind: `zone`  
   * phase: `http_response_cache_settings`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add rules to the ruleset. Alternatively, include the rules in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.

## Example requests

These examples demonstrate all the available actions in Cache Response Rules using request and response matching criteria. Using these examples directly will cause any existing rules in the phase to be replaced.

Example: Strip response headers from JS files before caching

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_cache_settings/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "http.request.uri.path.extension eq \"js\"",

            "description": "Strip caching headers from JS files",

            "action": "set_cache_settings",

            "action_parameters": {

                "strip_etags": true,

                "strip_set_cookie": true,

                "strip_last_modified": true

            }

        }

    ]

  }'


```

Example: Set static cache tags on API responses

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_cache_settings/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "http.request.uri.path starts_with \"/api/\"",

            "description": "Tag API responses for targeted purging",

            "action": "set_cache_tags",

            "action_parameters": {

                "operation": "set",

                "values": [

                    "api-response",

                    "dynamic-content"

                ]

            }

        }

    ]

  }'


```

Example: Add cache tags from a response header using an expression

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_cache_settings/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "any(http.response.headers.names[*] == \"Surrogate-Keys\")",

            "description": "Extract cache tags from alternative CDN response header",

            "action": "set_cache_tags",

            "action_parameters": {

                "operation": "add",

                "expression": "split(http.response.headers[\"Surrogate-Keys\"][0], \",\", 1)"

            }

        }

    ]

  }'


```

Example: Override cache-control with max-age 

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_cache_settings/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "http.response.code eq 200",

            "description": "Override cache-control for successful responses",

            "action": "set_cache_control",

            "action_parameters": {

                "max-age": {

                    "operation": "set",

                    "value": 3600,

                    "cloudflare_only": true

                }

            }

        }

    ]

  }'


```

Example: Set private directive with qualifiers

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_cache_settings/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "http.request.uri.path starts_with \"/user/\"",

            "description": "Mark user content as private",

            "action": "set_cache_control",

            "action_parameters": {

                "private": {

                    "operation": "set",

                    "qualifiers": [

                        "X-User-Id",

                        "X-Session-Token"

                    ]

                },

                "no-cache": {

                    "operation": "set"

                }

            }

        }

    ]

  }'


```

Example: Set immutable for static font assets

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_cache_settings/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "http.request.uri.path.extension in {\"woff2\" \"woff\" \"ttf\"}",

            "description": "Mark fonts as immutable",

            "action": "set_cache_control",

            "action_parameters": {

                "immutable": {

                    "operation": "set"

                },

                "max-age": {

                    "operation": "set",

                    "value": 31536000

                }

            }

        }

    ]

  }'


```

Example: Multiple rules with strip headers, tag responses, and set cache control

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_cache_settings/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "http.response.code eq 200 and http.request.uri.path.extension eq \"html\"",

            "description": "Strip tracking headers from HTML responses",

            "action": "set_cache_settings",

            "action_parameters": {

                "strip_etags": true,

                "strip_set_cookie": true

            }

        },

        {

            "expression": "http.request.uri.path starts_with \"/products/\"",

            "description": "Tag product pages for purging",

            "action": "set_cache_tags",

            "action_parameters": {

                "operation": "add",

                "values": [

                    "product-catalog",

                    "storefront"

                ]

            }

        },

        {

            "expression": "http.response.code eq 200",

            "description": "Set cache control for all 200 responses",

            "action": "set_cache_control",

            "action_parameters": {

                "s-maxage": {

                    "operation": "set",

                    "value": 86400,

                    "cloudflare_only": true

                },

                "must-revalidate": {

                    "operation": "set"

                }

            }

        }

    ]

  }'


```

## Required API token permissions

The API token used in API requests to manage Cache Response Rules must have the following permissions:

* _Zone_ \> _Cache Rules_ \> _Edit_
* _Account Rulesets_ \> _Edit_
* _Account Filter Lists_ \> _Edit_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-response-rules/","name":"Cache Response Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-response-rules/create-api/","name":"Create a rule via API"}}]}
```

---

---
title: Create a rule in the dashboard
description: If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to Troubleshooting for more information.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-response-rules/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a rule in the dashboard

1. In the Cloudflare dashboard, go to **Cache** \> **Cache Rules**.  
[ Go to **Cache Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules)
2. Select the **Cache Response Rules** tab.
3. Select **Create rule**.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, select **All incoming requests** if you want the rule to apply to all traffic or **Custom filter expression** if you want the rule to only apply to traffic matching the custom expression.
6. If you selected **Custom filter expression**, define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-builder). Use the **Field** drop-down list to choose an HTTP property and select an **Operator**. Both request fields (such as URI path or hostname) and response fields (such as response status code or response headers) are available for matching. Refer to [Available settings](https://developers.cloudflare.com/cache/how-to/cache-response-rules/settings/) for the full list of available fields and operators.  
Note  
Rules can be further customized by using the **Edit expression** option. You can find more information in [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).
7. Following the selection of the field and operator, enter the corresponding value that will trigger the Cache Response Rule. For example, if the selected field is `Hostname` and the operator is `equals`, a value of `example.com` would mean the rule matches any request to that hostname.
8. Under **Then**, select one of the following actions:  
   * **Modify cache-control directives**: Set or remove `Cache-Control` directives sent by your origin. For each directive, choose **Set directive** or **Remove directive**. For duration-based directives like `max-age` or `s-maxage`, enter a value in seconds. Turn on **Cloudflare only** to apply the directive only within Cloudflare's cache without changing what visitors receive. Refer to [Supported directives](https://developers.cloudflare.com/cache/how-to/cache-response-rules/settings/#supported-directives) for the full list.  
   * **Modify cache tags**: Add, override, or remove cache tags on the response for targeted [purging](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/). Select one of the following operations:  
         * **Add to existing tags**: Append new tags to the current set.  
         * **Override existing tags**: Replace all current tags with the specified tags.  
         * **Remove from existing tags**: Remove specific tags from the current set.  
   For the tag source, you can either specify tags manually or select **Parse from response header** to extract tags from a response header value. When parsing from a header, you can split the header value using a custom separator (for example, commas instead of spaces).  
   * **Strip headers**: Remove `Set-Cookie`, `ETag`, or `Last-Modified` headers from the origin response before Cloudflare evaluates the response for caching. Select which headers to strip.  
For more details on each action, refer to [Available settings](https://developers.cloudflare.com/cache/how-to/cache-response-rules/settings/#available-actions).
9. Under **Place at**, from the dropdown, you can select the order of your rule. From the main page, you can also change the order of the rules you have created.
10. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.

If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-response-rules/","name":"Cache Response Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-response-rules/create-dashboard/","name":"Create a rule in the dashboard"}}]}
```

---

---
title: Available settings
description: These are the settings that you can configure when creating a Cache Response Rule. Because Cache Response Rules execute after Cloudflare receives the origin response, both request and response fields are available for rule matching.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-response-rules/settings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Available settings

These are the settings that you can configure when creating a Cache Response Rule. Because Cache Response Rules execute after Cloudflare receives the origin response, both request and response fields are available for rule matching.

## Expression fields

### Request fields

| Field                            | Type   | Description                                    |
| -------------------------------- | ------ | ---------------------------------------------- |
| http.cookie                      | String | Full cookie header value                       |
| http.host                        | String | The HTTP Host header                           |
| http.referer                     | String | The HTTP Referer header                        |
| http.user\_agent                 | String | The HTTP User-Agent header                     |
| http.request.method              | String | The HTTP request method                        |
| http.request.uri                 | String | The request URI                                |
| http.request.uri.path            | String | The URI path                                   |
| http.request.uri.path.basename   | String | The basename of the URI path                   |
| http.request.uri.path.extension  | String | The file extension from the URI path           |
| http.request.uri.query           | String | The query string                               |
| http.request.uri.args            | Map    | Query string arguments as key-value pairs      |
| http.request.uri.args.names      | Array  | Query string argument names                    |
| http.request.uri.args.values     | Array  | Query string argument values                   |
| http.request.full\_uri           | String | The full request URI including scheme and host |
| http.request.headers             | Map    | Request headers as key-value pairs             |
| http.request.headers.names       | Array  | Request header names                           |
| http.request.headers.values      | Array  | Request header values                          |
| http.request.cookies             | Map    | Parsed cookies as key-value pairs              |
| http.request.accepted\_languages | Array  | Parsed Accept-Language header values           |

### Response fields

| Field                        | Type    | Description                                   |
| ---------------------------- | ------- | --------------------------------------------- |
| http.response.code           | Integer | The HTTP response status code from the origin |
| http.response.headers        | Map     | Response headers as key-value pairs           |
| http.response.headers.names  | Array   | Response header names                         |
| http.response.headers.values | Array   | Response header values                        |

If you select the [Edit expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-editor) option, you can enter any of the above response fields.

## Functions

The following functions are available in this phase:

* all
* any
* concat
* decode\_base64
* ends\_with
* len
* lookup\_json\_integer
* lookup\_json\_string
* lower
* regex\_replace
* remove\_bytes
* remove\_query\_args
* split
* starts\_with
* substring
* to\_string
* upper
* url\_decode
* wildcard\_replace

For descriptions of each function, refer to [Functions](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/).

## Operators

For the full list of operators, refer to [Operators](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/).

## Available actions

Cache Response Rules support three actions:

| Action               | Description                                                                               |
| -------------------- | ----------------------------------------------------------------------------------------- |
| set\_cache\_settings | Strip headers (ETags, Set-Cookie, Last-Modified) from the origin response before caching. |
| set\_cache\_tags     | Add, remove, or set cache tags on the response for targeted purging.                      |
| set\_cache\_control  | Modify Cache-Control header directives in the origin response.                            |

---

### Action: set\_cache\_settings

Configures settings related to caching on the origin response. The following parameters are available:

| Parameter             | Type    | Description                                                          |
| --------------------- | ------- | -------------------------------------------------------------------- |
| strip\_etags          | Boolean | Strip ETag headers from the origin response before caching.          |
| strip\_set\_cookie    | Boolean | Strip Set-Cookie headers from the origin response before caching.    |
| strip\_last\_modified | Boolean | Strip Last-Modified headers from the origin response before caching. |

Note

If `strip_etags` or `strip_last_modified` is `true` after all matching rules are applied, [Smart Edge Revalidation ↗](https://blog.cloudflare.com/introducing-smart-edge-revalidation/) is disabled for the origin response.

API information

API action: `set_cache_settings`.

API configuration example

```

"action_parameters": {

  "strip_etags": true,

  "strip_set_cookie": true,

  "strip_last_modified": true

}


```

Refer to [Create a rule via API](https://developers.cloudflare.com/cache/how-to/cache-response-rules/create-api/) for complete API examples.

---

### Action: set\_cache\_tags

Modifies the cache tags associated with the response. Cache tags can be used for targeted [cache purging](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/).

| Parameter  | Type   | Description                                                                             |
| ---------- | ------ | --------------------------------------------------------------------------------------- |
| operation  | String | **Required.** One of: add, remove, set.                                                 |
| values     | Array  | A list of cache tag strings. Mutually exclusive with expression.                        |
| expression | String | An expression that evaluates to an array of cache tags. Mutually exclusive with values. |

API information

API action: `set_cache_tags`.

API configuration example (static values)

```

"action_parameters": {

  "operation": "set",

  "values": ["api-response", "dynamic-content"]

}


```

API configuration example (expression)

```

"action_parameters": {

  "operation": "add",

  "expression": "split(http.response.headers[\"Surrogate-Keys\"][0], \",\", 1)"

}


```

Refer to [Create a rule via API](https://developers.cloudflare.com/cache/how-to/cache-response-rules/create-api/) for complete API examples.

---

### Action: set\_cache\_control

Modifies Cache-Control header directives in the origin response.

#### Supported directives

**Directives with duration value (seconds):**

* `max-age`
* `s-maxage`
* `stale-if-error`
* `stale-while-revalidate`

**Directives with optional qualifiers (header names):**

* `private`
* `no-cache`

**Boolean directives:**

* `no-store`
* `no-transform`
* `must-revalidate`
* `proxy-revalidate`
* `must-understand`
* `public`
* `immutable`

#### Directive configuration

The available parameters depend on the directive type.

##### Directives with duration value

Applies to `max-age`, `s-maxage`, `stale-if-error`, and `stale-while-revalidate`.

| Parameter        | Type    | Description                                                                                                                     |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| operation        | String  | **Required.** set or remove.                                                                                                    |
| cloudflare\_only | Boolean | When enabled, this setting only affects how Cloudflare caches your content. Your visitors still receive the original directive. |
| value            | Integer | Duration in seconds. **Required when operation is set.**                                                                        |

##### Directives with optional qualifiers

Applies to `private` and `no-cache`.

| Parameter        | Type    | Description                                                                                                                     |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| operation        | String  | **Required.** set or remove.                                                                                                    |
| cloudflare\_only | Boolean | When enabled, this setting only affects how Cloudflare caches your content. Your visitors still receive the original directive. |
| qualifiers       | Array   | Optional list of header names to qualify the directive.                                                                         |

##### Boolean directives

Applies to `no-store`, `no-transform`, `must-revalidate`, `proxy-revalidate`, `must-understand`, `public`, and `immutable`.

| Parameter        | Type    | Description                                                                                                                     |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| operation        | String  | **Required.** set or remove.                                                                                                    |
| cloudflare\_only | Boolean | When enabled, this setting only affects how Cloudflare caches your content. Your visitors still receive the original directive. |

API information

API action: `set_cache_control`.

API configuration example

```

"action_parameters": {

  "max-age": {

    "operation": "set",

    "value": 3600,

    "cloudflare_only": true

  },

  "stale-if-error": {

    "operation": "remove"

  }

}


```

Refer to [Create a rule via API](https://developers.cloudflare.com/cache/how-to/cache-response-rules/create-api/) for complete API examples.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-response-rules/","name":"Cache Response Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-response-rules/settings/","name":"Available settings"}}]}
```

---

---
title: Terraform example
description: The following example defines a single Cache Response Rule for a zone using Terraform. The rule strips Set-Cookie and ETag headers from JavaScript file responses before caching.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-response-rules/terraform-example.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Terraform example

The following example defines a single Cache Response Rule for a zone using Terraform. The rule strips Set-Cookie and ETag headers from JavaScript file responses before caching.

Terraform `cloudflare_ruleset` resource

```

# Cache Response Rule to strip headers from JS responses

resource "cloudflare_ruleset" "cache_response_rules_example" {

  zone_id     = "<ZONE_ID>"

  name        = "Cache Response Rules"

  description = "Configure cache settings for origin responses"

  kind        = "zone"

  phase       = "http_response_cache_settings"


  rules {

    ref         = "strip_js_headers"

    description = "Strip caching headers from JS file responses"

    expression  = "http.request.uri.path.extension eq \"js\""

    action      = "set_cache_settings"

    action_parameters {

      strip_etags      = true

      strip_set_cookie = true

    }

  }


  rules {

    ref         = "tag_api_responses"

    description = "Tag API responses for targeted purging"

    expression  = "starts_with(http.request.uri.path, \"/api/\")"

    action      = "set_cache_tags"

    action_parameters {

      operation = "set"

      values    = ["api-response", "dynamic-content"]

    }

  }


  rules {

    ref         = "cache_control_200"

    description = "Set cache-control for successful responses"

    expression  = "http.response.code eq 200"

    action      = "set_cache_control"

    action_parameters {

      s_maxage {

        operation      = "set"

        value          = 86400

        cloudflare_only = true

      }

      must_revalidate {

        operation = "set"

      }

    }

  }

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

For additional guidance on using Terraform with Cloudflare, refer to [Terraform](https://developers.cloudflare.com/terraform/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-response-rules/","name":"Cache Response Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-response-rules/terraform-example/","name":"Terraform example"}}]}
```

---

---
title: Cache Rules
description: Use Cache Rules to customize cache settings on Cloudflare. Cache Rules allows you to make adjustments to what is eligible to cache, how long it should be cached and where, as well as trigger specific interactions with Cloudflare's cache and other Rules products for matching requests.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Rules

Use Cache Rules to customize cache settings on Cloudflare. Cache Rules allows you to make adjustments to what is eligible to cache, how long it should be cached and where, as well as trigger specific interactions with Cloudflare's cache and other Rules products for matching requests.

Cache Rules can be created in the [dashboard](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/), via [API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/) or [Terraform](https://developers.cloudflare.com/cache/how-to/cache-rules/terraform-example/).

Notes

Cache Rules require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

Rules can be versioned. Refer to the [Version Management](https://developers.cloudflare.com/version-management/) documentation for more information.

## Rules templates

Cloudflare provides you with rules templates for common use cases.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Templates**, and then select one of the available templates.

You can also refer to the [Examples gallery](https://developers.cloudflare.com/rules/examples/) in the developer docs.

## Availability

The following table describes Cache Rules availability per plan.

| Free            | Pro | Business | Enterprise |     |
| --------------- | --- | -------- | ---------- | --- |
| Availability    | Yes | Yes      | Yes        | Yes |
| Number of rules | 10  | 25       | 50         | 300 |

## Troubleshooting

When troubleshooting Cache Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}}]}
```

---

---
title: Create a rule via API
description: Use the Rulesets API to create a cache rule via API. To configure Cloudflare’s API refer to the API documentation.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create a cache rule via API. To configure Cloudflare’s API refer to the [API documentation](https://developers.cloudflare.com/fundamentals/api/get-started/).

## Basic rule settings

When creating a cache rule via API, make sure you:

* Set the rule action to `set_cache_settings`.
* Define the parameters in the `action_parameters` field according to the [settings](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/) you wish to override for matching requests.
* Deploy the rule to the `http_request_cache_settings` phase entry point ruleset.

## Procedure

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) method to obtain the list of rules already present in the `http_request_cache_settings` phase entry point ruleset.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * kind: `zone`  
   * phase: `http_request_cache_settings`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add a cache rule to the list of ruleset rules. Alternatively, include the rule in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.
4. (Optional) To update an existing cache rule, use the [Update a zone ruleset rule](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. For an example, refer to the section below.

## Example requests

These examples are setting all the Cache Rules of a zone to a single rule, since using these examples directly will cause any existing rules to be deleted.

Example: Cache everything for example.com

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "(http.host eq \"example.com\")",

            "description": "cache everything for example.com",

            "action": "set_cache_settings",

            "action_parameters": {

                "cache": true

            }

        }

    ]

  }'


```

Example: Extend read timeout for Android clients

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "(http.user_agent contains \"Android\")",

            "description": "extend read timeout for android clients",

            "action": "set_cache_settings",

            "action_parameters": {

                "cache": true,

                "read_timeout": 300

            }

        }

    ]

  }'


```

Example: Disable Cache Reserve for frequently updated assets

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "(starts_with(http.request.uri, \"/feed/\"))",

            "description": "disable cache reserve for frequently updated assets",

            "action": "set_cache_settings",

            "action_parameters": {

                "cache": true,

                "cache_reserve": {

                    "enabled": false

                }

            }

        }

    ]

  }'


```

Example: Turn off default cache TTLs

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "expression": "(http.host eq \"example.com\")",

            "description": "turn off default cache ttls",

            "action": "set_cache_settings",

            "action_parameters": {

                "cache": true,

                "edge_ttl": {

                    "mode": "bypass_by_default"

                }

            }

        }

    ]

  }'


```

Example: Update the position of an existing rule

Update a zone ruleset rule

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID/rules/$RULE_ID" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "expression": "(http.host eq \"example.com\")",

    "description": "cache everything for example.com",

    "action": "set_cache_settings",

    "action_parameters": {

        "cache": true

    },

    "enabled": true,

    "position": {

        "before": "da5e8e506c8e7877fe06cdf4c41add54"

    }

  }'


```

## Required API token permissions

The API token used in API requests to manage Cache Rules must have the following permissions:

* _Zone_ \> _Cache Rules_ \> _Edit_
* _Account Rulesets_ \> _Edit_
* _Account Filter Lists_ \> _Edit_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/create-api/","name":"Create a rule via API"}}]}
```

---

---
title: Create a rule in the dashboard
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a rule in the dashboard

1. In the Cloudflare dashboard, go to the **Cache Rules** page.  
[ Go to **Cache Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/cache-rules)
2. Select **Create rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, select **All incoming requests** if you want the rule to apply to all traffic or **Custom filter expression** if you want the rule to only apply to traffic matching the custom expression.
6. If you selected **Custom filter expression**, under **When incoming requests match**, define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-builder). Use the **Field** drop-down list to choose an HTTP property and select an **Operator**. Refer to [Available settings](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/) for the list of available fields and operators.  
![Select fields in the Expression Builder.](https://developers.cloudflare.com/_astro/select-fields.euDkKViI_ZPmSQ0.webp)
7. Following the selection of the field and operator, enter the corresponding value that will trigger the Cache Rule. For example, if the selected field is `Hostname` and the operator is `equals`, a value of `cloudflare.com` would mean the rule matches any request to that hostname.  
![Example rule](https://developers.cloudflare.com/_astro/example-rule.fBosjk1F_ZeT0Gp.webp)  
Note  
Rules can be further customized by using the **Edit expression** option. You can find more information in [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).
8. Under **Then**, in the **Cache eligibility** section, select [**Bypass cache**](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#bypass-cache) if you want matching requests to not be cacheable, or **Eligible for cache** if you want Cloudflare to attempt to cache them. Note that [cache-control headers](https://developers.cloudflare.com/cache/concepts/cache-control/) can also impact cache eligibility.
9. If you selected **Eligible for cache** in the previous step, you can customize the options described in the [Available settings](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/) section.
10. Under **Place at**, from the dropdown, you can select the order of your rule. From the main page, you can also change the order of the rules you have created.
11. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/create-dashboard/","name":"Create a rule in the dashboard"}}]}
```

---

---
title: Browser Cache TTL
description: Browser Cache TTL
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/browser-cache-ttl.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Browser Cache TTL

Browser Cache TTL

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to adjust browser cache TTL for caching resources in the browser to one day for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Browser TTL**: Override origin and use this TTL  
   * **Input time-to-live (TTL)**: _1 day_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/browser-cache-ttl/","name":"Browser Cache TTL"}}]}
```

---

---
title: Bypass Cache on Cookie
description: Bypass Cache on Cookie
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/bypass-cache-on-cookie.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Bypass Cache on Cookie

Bypass Cache on Cookie

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to bypass cache for requests containing cookie `test_cookie` for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com" AND Cookie contains "test-cookie"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com" and http.cookie contains "test-cookie")`
* **Then**:  
   * **Cache eligibility**: Bypass cache

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/bypass-cache-on-cookie/","name":"Bypass Cache on Cookie"}}]}
```

---

---
title: Cache Deception Armor
description: Cache Deception Armor
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/cache-deception-armor.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Deception Armor

Cache Deception Armor

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to protect against cache deception attacks for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Cache key  
         * **Cache deception armor**: On

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/cache-deception-armor/","name":"Cache Deception Armor"}}]}
```

---

---
title: Cache by Device Type
description: Cache by Device Type
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/cache-device-type.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache by Device Type

Cache by Device Type

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to cache content based on user agent or device type for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Cache key  
         * **Cache by device type**: On

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/cache-device-type/","name":"Cache by Device Type"}}]}
```

---

---
title: Cache Level (Cache Everything)
description: Cache Level (Cache Everything)
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/cache-everything.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Level (Cache Everything)

Cache Level (Cache Everything)

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to adjust cache level for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache

Warning

This option caches all HTML regardless of the presence of dynamic content. If you use this approach to cache pages containing dynamic content, visitors may receive information not intended for them. To avoid caching dynamic content, you can add a condition to the rule's matching criteria to prevent it from matching that content. Some examples include:

* Checking for the presence of a cookie.
* Negative matching against known dynamic content file paths.
* Negative matching against dynamic content extensions (or lack of an extension).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/cache-everything/","name":"Cache Level (Cache Everything)"}}]}
```

---

---
title: Cache Everything while ignoring query strings
description: Cache Everything while ignoring query strings
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/cache-everything-ignore-query-strings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Everything while ignoring query strings

Cache Everything while ignoring query strings

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to adjust cache level for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Cache key  
         * **Query string**: Ignore query string

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/cache-everything-ignore-query-strings/","name":"Cache Everything while ignoring query strings"}}]}
```

---

---
title: Cache TTL by status code
description: Cache TTL by status code
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/cache-ttl-by-status-code.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache TTL by status code

Cache TTL by status code

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to cache responses with status code between `200` and `599` for one day for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Edge TTL  
         * Use cache-control header if present, use default Cloudflare caching behavior if not  
         * **Status code TTL**:  
                  * **Scope**: _Range_  
                  * **From**: _200_  
                  * **To**: _599_  
                  * **Duration**: _1 day_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/cache-ttl-by-status-code/","name":"Cache TTL by status code"}}]}
```

---

---
title: Custom Cache Key
description: Custom Cache Key
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/custom-cache-key.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Custom Cache Key

Custom Cache Key

Note

If you are migrating from Page Rules and you want to keep Page Rules behavior, you need to create two specific rules before creating this rule. For more details refer to [Migration from Page Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to set a custom cache key for all query string parameters, for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Cache key  
         * **Query string**: All query string parameters

Refer to [cache keys](https://developers.cloudflare.com/cache/how-to/cache-keys/) for more information on possible settings when configuring a custom cache key.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/custom-cache-key/","name":"Custom Cache Key"}}]}
```

---

---
title: Edge Cache TTL
description: Edge Cache TTL
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/edge-ttl.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Edge Cache TTL

Edge Cache TTL

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to adjust edge cache TTL for caching resources on Cloudflare edge to one day, for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Edge TTL  
         * Ignore cache-control header and use this TTL  
                  * **Input time-to-live (TTL)**: _1 day_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/edge-ttl/","name":"Edge Cache TTL"}}]}
```

---

---
title: Origin Cache Control
description: Origin Cache Control
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/origin-cache-control.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Cache Control

Origin Cache Control

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to determine edge cache behavior for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Origin Cache Control  
         * **Enable Origin Cache Control**: Off

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/origin-cache-control/","name":"Origin Cache Control"}}]}
```

---

---
title: Query String Sort
description: Query String Sort
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/query-string-sort.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Query String Sort

Query String Sort

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to sort query string parameters for caching purposes, for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Cache key  
         * **Sort query string**: On

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/query-string-sort/","name":"Query String Sort"}}]}
```

---

---
title: Respect Strong ETags
description: Respect Strong ETags
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/examples/respect-strong-etags.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Respect Strong ETags

Respect Strong ETags

[Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to respect strong ETags for any hostname containing `example.com`:

* **When incoming requests match**: Custom filter expression  
   * Using the Expression Builder:  
   `Hostname contains "example.com"`  
   * Using the Expression Editor:  
   `(http.host contains "example.com")`
* **Then**:  
   * **Cache eligibility**: Eligible for cache  
   * **Setting**: Respect strong ETags  
         * **Use strong ETag headers**: On

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/examples/","name":"Examples"}},{"@type":"ListItem","position":6,"item":{"@id":"/cache/how-to/cache-rules/examples/respect-strong-etags/","name":"Respect Strong ETags"}}]}
```

---

---
title: Order and priority
description: Cache rules affect requests differently from Page Rules. This is how they are applied:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/order.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Order and priority

Cache rules affect requests differently from Page Rules. This is how they are applied:

1. Cache Rules are stackable. This means that multiple matching rules can be combined and applied to the same request. For example, if multiple cache rules match the same URL, then the features set in those cache rules will all be applied in order. If several matching rules set a value for the same setting, the value in the last matching rule wins. For an example of a similar scenario where multiple rules match, refer to the [Origin Rules FAQ](https://developers.cloudflare.com/rules/origin-rules/faq/#what-happens-if-more-than-one-origin-rule-matches-the-current-request).
2. For conflicting settings (for example, bypass cache versus eligible for cache), the last matching rule wins. For example, if cache rule #1 is set to cache everything on `example.com/images` and cache rule #2 is set to bypass cache on `example.com`, then cache will be bypassed for all URLs that match `example.com`, since rule #2 is the last matching rule.
3. If you have Page Rules implemented for caching on the same path, Cache Rules will take precedence by design.
4. Cache rules can be more specific than website-wide settings in the cache configuration tab, so they take precedence over website-wide settings on requests they match against. For example, if browser cache TTL is set to 4 hours for the entire website `example.com` and there is a cache rule matching requests with a path of `/feed` setting browser cache TTL to 10 seconds, the cache rule will override the website-wide setting for requests to `https://example.com/feed`.

## Execution order of Rules products

The execution order of Rules features is the following:

* [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/)
* [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/)
* [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/)
* [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/)
* [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/)
* [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/)
* [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/)
* [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
* [Snippets](https://developers.cloudflare.com/rules/snippets/)
* [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/)

The different types of rules listed above will take precedence over [Page Rules](https://developers.cloudflare.com/rules/page-rules/). This means that Page Rules will be overridden if there is a match for both Page Rules and the Rules products listed above.

Generally speaking, for [non-terminating actions](https://developers.cloudflare.com/ruleset-engine/rules-language/actions/) the last change made by rules in the same [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/) will win (later rules can overwrite changes done by previous rules). However, for terminating actions (_Block_, _Redirect_, or one of the challenge actions), rule evaluation will stop and the action will be executed immediately.

For example, if multiple rules with the _Redirect_ action match, Cloudflare will always use the URL redirect of the first rule that matches. Also, if you configure URL redirects using different Cloudflare products (Single Redirects and Bulk Redirects), the product executed first will apply, if there is a rule match (in this case, Single Redirects).

Refer to the [Phases list](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) for the product execution order.

Warning

Using Cloudflare challenges along with Rules features may cause challenge loops. Refer to [Rules troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/order/","name":"Order and priority"}}]}
```

---

---
title: Migration from Page Rules
description: If you are migrating from Page Rules, there is a behavior change between Page Rules and Cache Rules.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/page-rules-migration.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Migration from Page Rules

If you are migrating from Page Rules, there is a behavior change between Page Rules and Cache Rules.

When you create a new Cache Rule and select **Eligible for cache**, the Cache Everything feature is enabled by default. With Page Rules, you had to specifically enable the Cache Everything option.

To maintain the same behavior you had with Page Rules (that is, not enabling Cache Everything), you need to create these two specific rules in this order before creating any additional rules.

Multiple matching cache rules can be combined and applied to the same request. After rule 1 matches, Cloudflare will keep evaluating other cache rules checking for matches. For more information, refer to [Order and priority](https://developers.cloudflare.com/cache/how-to/cache-rules/order/).

## Rule 1

* [ Dashboard ](#tab-panel-3308)
* [ visual guide ](#tab-panel-3309)

1. Enter a rule name, for instance `bypass everything`.
2. In **When incoming requests match**, select **All incoming requests**.
3. Under **Then**, in the **Cache eligibility** section, select [Bypass cache](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#bypass-cache).

![Create rule to bypass cache](https://developers.cloudflare.com/_astro/first-rule.DCA_9a45_1jNULw.webp)

## Rule 2

* [ Dashboard ](#tab-panel-3310)
* [ visual guide ](#tab-panel-3311)

1. Enter a rule name, for instance `cache all default cacheable extensions`.
2. In **When incoming requests match**, select **Custom filter expression**.
3. Define the following rule:  
   * **Field**: `File extension`  
   * **Operator**: `is in`  
   * **Value**: `7z, avi, avif, apk, bin, bmp, bz2, class, css, csv, doc, docx, dmg, ejs, eot, eps, exe, flac, gif, gz, ico, iso, jar, jpg, jpeg, js, mid, midi, mkv, mp3, mp4, ogg, otf, pdf, pict, pls, png, ppt, pptx, ps, rar, svg, svgz, swf, tar, tif, tiff, ttf, webm, webp, woff, woff2, xls, xlsx, zip, zst`

If you prefer, you can select **Edit expression** and paste the following expression:

```

(http.request.uri.path.extension in {"7z" "avi" "avif" "apk" "bin" "bmp" "bz2" "class" "css" "csv" "doc" "docx" "dmg" "ejs" "eot" "eps" "exe" "flac" "gif" "gz" "ico" "iso" "jar" "jpg" "jpeg" "js" "mid" "midi" "mkv" "mp3" "mp4" "ogg" "otf" "pdf" "pict" "pls" "png" "ppt" "pptx" "ps" "rar" "svg" "svgz" "swf" "tar" "tif" "tiff" "ttf" "webm" "webp" "woff" "woff2" "xls" "xlsx" "zip" "zst"})


```

1. Under **Then**, in the **Cache eligibility** section, select [**Eligible for cache**](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#eligible-for-cache-settings).

![Create an eligible for cache rule](https://developers.cloudflare.com/_astro/second-rule.88NhnPNI_c13b4.webp)

Note

Remember to create the rules in the specified order: first, the `bypass everything` rule, and then the `cache all default cacheable file extensions` rule.

![Rules order](https://developers.cloudflare.com/_astro/rule-order.wNZiF99u_ZOuxf5.webp)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/page-rules-migration/","name":"Migration from Page Rules"}}]}
```

---

---
title: Available settings
description: These are the settings that you can configure when creating a cache rule.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/settings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Available settings

These are the settings that you can configure when creating a cache rule.

## Fields

The fields available for Cache Rule matching expressions in the **Expression Builder** are:

* URI Full - `http.request.full_uri`
* URI - `http.request.uri`
* URI Path - `http.request.uri.path`
* URI Query String - `http.request.uri.query`
* Cookie - `http.cookie`
* Hostname - `http.host`
* Referer - `http.referer`
* SSL/HTTPS - `ssl`
* User Agent - `http.user_agent`
* X-Forwarded-For - `http.x_forwarded_for`
* Request Headers - `http.request.headers`
* Cookie value of - `http.request.cookies`
* File extension - `http.request.uri.path.extension`

If you select the [Edit expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-editor) option, you can enter any of the [available fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/).

Note

[Single file purge](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/) is not compatible if you add other [fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) than those listed, such as `ip.*` fields.

## Operators

The operators available for Cache Rule expressions are:

* wildcard
* strict wildcard
* equals
* does not equal
* contains
* does not contain
* matches regex
* does not match regex
* starts with
* ends with
* does not start with
* does not end with
* is in
* is not in

Note

Not all operators are available for every selected field.

## Cache eligibility

In **Cache eligibility**, you have the option to select **Bypass cache** if you want matching requests to not be cached, or **Eligible for cache** if you want Cloudflare to attempt to cache them.

### Bypass cache

When creating a cache rule, you have the option to select **Bypass cache** if you want matching incoming requests to not be cached. Alternatively, you can use [Development Mode](https://developers.cloudflare.com/cache/reference/development-mode/), if you want to bypass cache for shorter periods.

Note

When using Custom Cache Rules with a Bypass setting, the response header may return [DYNAMIC](https://developers.cloudflare.com/cache/concepts/cache-responses/#dynamic) rather than explicitly indicating a bypass. This occurs because the rule makes the content ineligible for caching, even if the origin response is otherwise cacheable.

### Eligible for cache settings

When you select **Eligible for cache**, you can change the configuration settings described below.

Note

If you use cache rules, image transformations, and zone versioning simultaneously, some settings may not be applied correctly.

#### Edge TTL

Edge Cache TTL refers to the maximum cache time-to-live (TTL), or how long an asset should be considered fresh or available to serve from Cloudflare’s cache in response to requests. This setting has three primary options:

* **Use cache control-header if present, bypass cache if not**: If a cache-control header is present on the response, follow its directives. If not, skip caching entirely.
* **Use cache-control header if present, use default Cloudflare caching behavior if not**: If a cache-control header is present on the response, follow its directives. If not, cache in accordance with our [default edge TTL settings](https://developers.cloudflare.com/cache/how-to/configure-cache-status-code/#edge-ttl).
* **Ignore cache-control header and use this TTL**: Completely ignore any cache-control header on the response and instead cache the response for a duration specified in the timing dropdown.

Additionally, you can select how long you would like a particular matching status code's content to be cached in Cloudflare's global network. In **Status Code TTL** section you can define the TTL duration for one or more status codes of responses from the origin server. This setting can be applied to a _Single code_ status code, to a _Greater than or equal_ or _Less than or equal_ status code, or to a _Range_ of status codes. Status code TTLs are similar to **Ignore cache-control header and use this TTL** in that the cache-control header on the response will be ignored in favor of the TTL specified by the cache rule. For more information, refer to [Status code TTL](https://developers.cloudflare.com/cache/how-to/configure-cache-status-code/).

API information

API configuration object name: `"edge_ttl"`.

| API values          | Configuration                                                                                                                                                    |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| respect\_origin     | Use cache-control header if present, use default [Cloudflare caching behavior](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/) if not. |
| override\_origin    | Ignore cache-control header and use this TTL.                                                                                                                    |
| bypass\_by\_default | Use cache control-header if present, bypass cache if not.                                                                                                        |

API configuration example

```

"action_parameters": {

    "cache": true,

    "edge_ttl": {

        "status_code_ttl": [

            {

                "status_code_range": {

                    "to": 299

                },

                "value": 86400

            },

            {

                "status_code_range": {

                    "from": 300,

                    "to": 499

                },

                "value": 0  // no-cache

            },

            {

                "status_code_range": {

                    "from": 500

                },

                "value": -1  // no-store

            }

        ],

        "mode": "respect_origin"

    }

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Browser TTL

Browser TTL refers to the maximum cache time-to-live (TTL) that an asset should be considered available to serve from the browser’s cache.

Select if you want to **Bypass cache**, **Respect origin**, or **Override origin**. If you wish to override the browser TTL value, define how long resources cached by client browsers will remain valid from the dropdown menu. For more information, refer to [Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#browser-cache-ttl).

API information

API configuration object name: `"browser_ttl"`.

API values for the `"mode"` property: `"respect_origin"`, `"override_origin"`, `"bypass_by_default"`.   

API values for the `"default"` property (integer): values available depend on your plan. Refer to [Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#browser-cache-ttl).

API configuration example

```

"action_parameters": {

  "cache": true,

  "browser_ttl" : {

    "mode": "override_origin",

    "default": 1000

  }

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Cache Key

Cache keys refer to the criteria that Cloudflare uses to determine how to store resources in our cache. Customizing the Cache Key allows you to determine how Cloudflare can reuse particular cache entries across requests or share the cache entries for more granularity for end users.

Define the request components used to define a [custom Cache Key](https://developers.cloudflare.com/cache/how-to/cache-keys/), customizing the following options:

* You can switch on or off [Cache deception armor](https://developers.cloudflare.com/cache/cache-security/cache-deception-armor/), [Cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/), and [Sort query string](https://developers.cloudflare.com/cache/how-to/cache-keys/#query-string).

Enterprise customers have these additional options for custom Cache Keys:

* In the **Query string** section, you can select **All query string parameters**, **All query string parameters except** and enter an exception, **No query parameters except** and enter the parameters, or **Ignore query string** (also available for pay-as-you-go customers).
* In the **Headers** section, you can specify header names along with their values. For custom headers, values are optional; however, for the following restricted headers, you must include one to three specific values:  
   * `accept`  
   * `accept-charset`  
   * `accept-encoding`  
   * `accept-datetime`  
   * `accept-language`  
   * `referer`  
   * `user-agent`  
To check for a header's presence without including its value, use the **Check presence of** option. You can also choose whether to **Include origin header**.
* In the **Cookie** section, you can include cookie names and their values, and check for the presence of another cookie.
* In the **Host** section, you can select **Use original host** and **Resolved host**. In the **User** section, you can select **Device type**, **Country**, and **Language**. Using **Resolved host** means the Cache Key will contain whatever hostname was used to resolve the origin IP which can be different depending on whether the [resolve override](https://developers.cloudflare.com/rules/origin-rules/features/#dns-record) feature is on or not.

Note

When [URL normalization](https://developers.cloudflare.com/rules/normalization/) is enabled, we recommend also enabling [Normalize URLs to origin](https://developers.cloudflare.com/rules/normalization/manage/), especially if you are setting custom Cache Keys or using cache by device type, which also modifies the Cache Key. This helps ensure the URL in the Cache Key matches the URL sent to the origin, preventing cache poisoning and ensuring consistent behavior.

API information

API configuration object name: `"cache_key"`.

API values: `"ignore_query_strings_order"`, `"cache_deception_armor"`, `"cache_by_device_type"`, `"custom_key"` (`"header"`, `"cookie"`, `"host"`, `"query_string"`, `"user"`).

API configuration example

```

"action_parameters": {

  "cache": true,

  "cache_key": {

    "ignore_query_strings_order": true,

    "cache_deception_armor": true,

    "custom_key": {

      "query_string": {

        "include": [

          "*"

        ]

      },

      "header": {

        "include": [

          "header1"

        ],

        "check_presence": [

          "header_1"

        ],

        "contains": {

          "accept-encoding": ["br", "zstd"]

        }

      },

      "cookie": {

        "include": [

          "cookieName1"

        ],

        "check_presence": [

          "cookie_1"

        ]

      },

      "user": {

        "device_type": true,

        "geo": true,

        "lang": true

      },

      "host": {

        "resolved": false

      }

    }

  }

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Cache Reserve Eligibility

Cache Reserve eligibility allows you to specify which website resources should be eligible for our persistent cache called [Cache Reserve](https://developers.cloudflare.com/cache/advanced-configuration/cache-reserve/). If the request matches and also meets [eligibility criteria](https://developers.cloudflare.com/cache/advanced-configuration/cache-reserve/#cache-reserve-asset-eligibility), Cloudflare will write the resource to cache reserve. This requires an add-on cache reserve plan.

This rule can also be used to specify Cache Reserve eligibility for website resources based on their size. For example, by specifying that all assets which are eligible be 100 MB and above, Cloudflare will look for eligible assets at or above 100 MB for Cache Reserve eligibility and only persistently store those assets.

Note

Cloudflare will still enforce the plan-based [cacheable file limits](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#customization-options-and-limits) when using this configuration.

API information

API configuration object name: `"cache_reserve"`.

API property name for enabling Cache Reserve: `"eligible"` (boolean).

API configuration example

```

"action_parameters": {

  "cache": true

  "cache_reserve": {

    "eligible": true,

    "minimum_file_size": 100000

  }

}


```

Note

If `minimum_file_size` is omitted and `eligible` is true, Cloudflare will use 0 bytes by default.

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Caching on Port (Enterprise-only)

Cloudflare supports several [network ports](https://developers.cloudflare.com/fundamentals/reference/network-ports/#network-ports-compatible-with-cloudflares-proxy) by default, like 80 or 443\. Some ports, traditionally admin ports, are supported but have caching disabled as they are used to manage sensitive information that should be ineligible for cache. Enterprise customers wanting to enable caching on these admin ports can cache on these ports by entering their desired port.

Note

Cloudflare supports many ports by default and will cache on them without needing this rule to be configured. For ports that Cloudflare supports, but for which caching is disabled, use this rule.

API information

API configuration property name: `"additional_cacheable_ports"` (array of integer values).

API configuration example

```

"action_parameters": {

    "cache": true

    "additional_cacheable_ports": [8443, 8080]

  }

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Proxy Read Timeout (Enterprise-only)

Defines a timeout value between two successive read operations to your origin server. The default value can be found in the [Connection limits](https://developers.cloudflare.com/fundamentals/reference/connection-limits/) table. If you are attempting to reduce [HTTP 524](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-524/) errors because of timeouts from an origin server, try increasing this timeout value using the API endpoint below.

API information

API configuration property name: `"read_timeout"` (integer).

API configuration example

```

"action_parameters": {

  "cache": true,

  "read_timeout": 900

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Serve stale content while revalidating

Defines if Cloudflare will serve stale content while updating the latest content from the origin server. If serving stale content is disabled, Cloudflare will not serve stale content while getting the latest content from the origin.

API information

API configuration property name: `"serve_stale"` \> `"disable_stale_while_updating"` (boolean).

API configuration example

```

"action_parameters": {

  "cache": true,

  "serve_stale": {

    "disable_stale_while_updating": true

  }

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Respect Strong ETags

Turn on or off byte-for-byte equivalency checks between the Cloudflare cache and the origin server. When enabled, Cloudflare will use [strong ETag](https://developers.cloudflare.com/cache/reference/etag-headers/#strong-etags) header validation to ensure that resources in the Cloudflare cache and on the origin server are byte-for-byte identical. If disabled, Cloudflare converts ETag headers into [weak ETag](https://developers.cloudflare.com/cache/reference/etag-headers/#weak-etags) headers.

API information

API configuration property name: `"respect_strong_etags"` (boolean).

API configuration example

```

"action_parameters": {

  "cache": true,

  "respect_strong_etags": true

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Origin error page pass-through

Turn on or off Cloudflare error pages generated from error HTTP status codes sent from the origin server. If enabled, this setting enables the use of error pages issued by the origin.

API information

API configuration property name: `"origin_error_page_passthru"` (boolean).

API configuration example

```

"action_parameters": {

  "cache": true,

  "origin_error_page_passthru": true

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

#### Origin Cache Control (Enterprise-only)

When this option is enabled, Cloudflare will aim to strictly adhere to [RFC 7234 ↗](https://datatracker.ietf.org/doc/html/rfc7234). Enterprise customers have the ability to select if Cloudflare will adhere to this behavior. Free, Pro, and Business customers have this option enabled by default and cannot disable it.

API information

API configuration property name: `"origin_cache_control"` (boolean).

API configuration example

```

"action_parameters": {

  "cache": true

  "origin_cache_control": true

}


```

Refer to [Create a cache rule via API](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests) for complete API examples.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/settings/","name":"Available settings"}}]}
```

---

---
title: Terraform example
description: The following example defines a single cache rule for a zone using Terraform. The rule configures several cache settings and sets a custom cache key for incoming requests addressed at example.net.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/cache-rules/terraform-example.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Terraform example

The following example defines a single cache rule for a zone using Terraform. The rule configures several cache settings and sets a custom cache key for incoming requests addressed at `example.net`.

Terraform `cloudflare_ruleset` resource

```

# Cache rule configuring cache settings and defining custom cache keys

resource "cloudflare_ruleset" "cache_rules_example" {

  zone_id     = "<ZONE_ID>"

  name        = "Set cache settings"

  description = "Set cache settings for incoming requests"

  kind        = "zone"

  phase       = "http_request_cache_settings"


  rules {

    ref         = "cache_settings_custom_cache_key"

    description = "Set cache settings and custom cache key for example.net"

    expression  = "(http.host eq \"example.net\")"

    action      = "set_cache_settings"

    action_parameters {

      edge_ttl {

        mode    = "override_origin"

        default = 60

        status_code_ttl {

          status_code = 200

          value       = 50

        }

        status_code_ttl {

          status_code_range {

            from = 201

            to   = 300

          }

          value = 30

        }

      }

      browser_ttl {

        mode = "respect_origin"

      }

      serve_stale {

        disable_stale_while_updating = true

      }

      respect_strong_etags = true

      cache_key {

        ignore_query_strings_order = false

        cache_deception_armor      = true

        custom_key {

          query_string {

            exclude {

              all = true

            }

          }

          header {

            include        = ["habc", "hdef"]

            check_presence = ["habc_t", "hdef_t"]

            exclude_origin = true

          }

          cookie {

            include        = ["cabc", "cdef"]

            check_presence = ["cabc_t", "cdef_t"]

          }

          user {

            device_type = true

            geo         = false

          }

          host {

            resolved = true

          }

        }

      }

      origin_error_page_passthru = false

    }

  }

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

For additional guidance on using Terraform with Cloudflare, refer to [Terraform](https://developers.cloudflare.com/terraform/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/cache-rules/","name":"Cache Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/cache-rules/terraform-example/","name":"Terraform example"}}]}
```

---

---
title: Cache by status code
description: Customers can set cache time-to-live (TTL) based on the response status from the origin web server. Cache TTL refers to the duration of a resource in the Cloudflare network before being marked as STALE or discarded from cache. Status codes are returned by a resource's origin.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/configure-cache-status-code.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache by status code

Customers can set cache time-to-live (TTL) based on the response status from the origin web server. Cache TTL refers to the duration of a resource in the Cloudflare network before being marked as `STALE` or discarded from cache. Status codes are returned by a resource's origin.

Setting cache TTL based on response status overrides the [default cache behavior (standard caching)](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/) for static files and overrides cache instructions sent by the origin web server. To cache non-static assets, set a [Cache Level of Cache Everything using a Cache Rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-api/#example-requests). Setting `no-store` **Cache-Control** or a low TTL (using `max-age`/`s-maxage`) increases requests to origin web servers and decreases performance.

## Caching limits

The maximum caching limit for Free, Pro, and Business customers is 512 MB per file, and the maximum caching limit for Enterprise customers is 5 GB per file. If you need to raise the limits, contact your Customer Success Manager.

## Edge TTL

By default, Cloudflare caches certain HTTP response codes with the following Edge Cache TTL when a `cache-control` directive or `expires` response header are not present.

| HTTP status code | Default TTL |
| ---------------- | ----------- |
| 200, 206, 301    | 120m        |
| 302, 303         | 20m         |
| 404, 410         | 3m          |

All other status codes are not cached by default.

## Set cache TTL by response status via the Cloudflare dashboard

To set cache TTL by response status, [create a Cache Rule](https://developers.cloudflare.com/cache/how-to/cache-rules/) for [**Cache TTL by status code**](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl).

## Set cache TTL by response status via the Cloudflare API

Request

```

curl --request PUT \

"https://api.cloudflare.com/client/v4/zones/{zone_id}/rulesets/{ruleset_id}" \

--header "Authorization: Bearer <API_TOKEN>" \

--header "Content-Type: application/json" \

--data '{

  "rules": [

    {

      "expression": "(http.host eq \"www.example.com\")",

      "description": "set cache TTL by response status",

      "action": "set_cache_settings",

      "action_parameters": {

        "cache": true,

        "edge_ttl": {

          "status_code_ttl": [

            {

              "status_code_range": {

                "to": 299

              },

              "value": 86400

            },

            {

              "status_code_range": {

                "from": 300,

                "to": 499

              },

              "value": 0  // no-cache

            },

            {

              "status_code_range": {

                "from": 500

              },

              "value": -1  // no-store

            }

          ],

          "mode": "respect_origin"

        }

      }

    }

  ]

}'


```

### Syntax

Provide a JSON object containing status codes and their corresponding TTLs. Each key-value pair in the cache TTL by status cache rule has the following syntax:

* `status_code`: An integer value such as 200 or 500\. `status_code` matches the exact status code from the origin web server. Valid status codes are between 100-999.
* `status_code_range`: Integer values for `from` and `to`. `status_code_range` matches any status code from the origin web server within the specified range.
* `value`: An integer value that defines the duration an asset is valid in seconds or one of the following strings: `no-store` (equivalent to `-1`), `no-cache` (equivalent to `0`).

## Set cache TTL by response status via a Cloudflare Worker

The **cacheTtlByStatus** option is a version of the **cacheTtl** feature that designates a cache TTL for a request’s response status code (for example, `{ "200-299": 86400, 404: 1, "500-599": 0 }`).

## TTL handling for 304 and 200 status codes

1. If a TTL is not explicitly set for status code `304`, we automatically set it to match the TTL of status code `200` (if the user has defined one for `200`).
2. If a user explicitly sets a different TTL for `304` than for `200`, the following behavior will occur:
* When a `200` response is received, the asset is cached with the TTL specified for status `200`.
* Once the asset expires and we revalidate with the origin, if the origin returns a `304`, the cache TTL is updated to the value set for `304`.

For example, if a user specifies a TTL of one hour for status `200` and 0 seconds (cache and always revalidate) for status `304`, the asset will be cached for 1 hour. After it expires, we revalidate with the origin. If the origin returns a `304`, each subsequent request will trigger revalidation. If the origin continues to return `304`, this cycle will persist.

This behavior is likely undesirable unless the user has a specific use case. Therefore, users should ensure that the TTL for `304` matches the TTL for `200` unless they intentionally require this behavior.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/configure-cache-status-code/","name":"Cache by status code"}}]}
```

---

---
title: Edge and Browser Cache TTL
description: Edge Cache TTL (Time to Live) specifies the maximum time to cache a resource in the Cloudflare global network. Edge Cache TTL is not visible in response headers and the minimum Edge Cache TTL depends on plan type.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/edge-browser-cache-ttl/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Edge and Browser Cache TTL

## Edge Cache TTL

Edge Cache TTL (Time to Live) specifies the maximum time to cache a resource in the Cloudflare global network. Edge Cache TTL is not visible in response headers and the minimum Edge Cache TTL depends on plan type.

| Free                   | Pro     | Business | Enterprise |          |
| ---------------------- | ------- | -------- | ---------- | -------- |
| Availability           | Yes     | Yes      | Yes        | Yes      |
| Minimum Edge Cache TTL | 2 hours | 1 hour   | 1 second   | 1 second |

For more information on how to set up Edge Cache TTL, refer to [Cache rules](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl).

## Browser Cache TTL

The Browser Cache TTL sets the expiration for resources cached in a visitor’s browser. By default, Cloudflare honors the cache expiration set in your `Expires` and `Cache-Control` headers but overrides those headers if:

* The value of the `Expires` or `Cache-Control` header from the origin web server is less than the Browser Cache TTL Cloudflare setting.
* The origin web server does not send a `Cache-Control` or an `Expires` header.

Unless specifically set in a cache rule, Cloudflare does not override or insert `Cache-Control` headers if you set **Browser Cache TTL** to **Respect Existing Headers**.

Note

* Setting high Browser Cache TTL values means that the assets will be cached for a long time by users’ browsers.
* If you modify cached assets, the new assets may not be displayed to repeat visitors before the Browser Cache TTL expires.
* Purging Cloudflare’s cache does not affect assets stored by a visitor’s browser.

| Free                                   | Pro       | Business  | Enterprise |            |
| -------------------------------------- | --------- | --------- | ---------- | ---------- |
| Availability                           | Yes       | Yes       | Yes        | Yes        |
| Minimum Browser Cache TTL (Page Rules) | 2 minutes | 2 minutes | 2 minutes  | 30 seconds |
| Minimum Browser Cache TTL              | 1 second  | 1 second  | 1 second   | 1 second   |
| Default Browser Cache TTL              | 4 hours   | 4 hours   | 4 hours    | 4 hours    |

For more information on setting the Browser Cache TTL, refer to [Set Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/set-browser-ttl/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/edge-browser-cache-ttl/","name":"Edge and Browser Cache TTL"}}]}
```

---

---
title: Set Browser Cache TTL
description: Specify a time for a visitor’s Browser Cache TTL to accelerate the page load for repeat visitors to your website. To configure cache duration within Cloudflare’s data centers, refer to Edge Cache TTL.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/edge-browser-cache-ttl/set-browser-ttl.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Set Browser Cache TTL

Specify a time for a visitor’s Browser Cache TTL to accelerate the page load for repeat visitors to your website. To configure cache duration within Cloudflare’s data centers, refer to [Edge Cache TTL](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl).

By default, Cloudflare honors the cache expiration set in your `Expires` and `Cache-Control` headers. Cloudflare overrides any `Cache-Control` or `Expires` headers with values set via the **Browser Cache TTL** option under **Caching** on your dashboard if:

* The value of the `Cache-Control` header from the origin web server is less than the **Browser Cache TTL** setting. This means that **Browser cache TTL** value needs to be higher than origin `max-age`.
* The origin web server does not send a `Cache-Control` or an `Expires` header.

Unless specifically set in a [Cache Rule](https://developers.cloudflare.com/cache/how-to/cache-rules/), Cloudflare does not override or insert `Cache-Control` headers if you set **Browser Cache TTL** to **Respect Existing Headers**.

Nevertheless, the value you set via Cache Rule will be ignored if `Cache-Control: max-age` is higher. In other words, you can override to make browsers cache longer than Cloudflare's edge but not less.

## Set Browser Cache TTL

Note

If you modify cached assets, the new asset is not displayed to repeat visitors before the Browser Cache TTL duration. [Purging Cloudflare’s cache](https://developers.cloudflare.com/cache/how-to/purge-cache/) does not affect assets cached in a visitor’s browser.

1. In the Cloudflare dashboard, go to the **Caching** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Under **Browser Cache TTL**, select the desired cache expiration time from the drop-down menu.

The **Respect Existing Headers** option tells Cloudflare to honor the settings in the `Cache-Control` headers from your origin web server.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/edge-browser-cache-ttl/","name":"Edge and Browser Cache TTL"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/edge-browser-cache-ttl/set-browser-ttl/","name":"Set Browser Cache TTL"}}]}
```

---

---
title: Purge cache
description: Cloudflare's Instant Purge ensures that updates to your content are reflected immediately. Multiple options are available for purging content, with single-file cache purging (purge by URL) being the recommended method. However, the following additional options are also available:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Purge cache

Cloudflare's Instant Purge ensures that updates to your content are reflected immediately. Multiple options are available for purging content, with single-file cache purging (purge by URL) being the recommended method. However, the following additional options are also available:

* [ ​Purge by single-file ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/)
* [ ​Purge everything ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-everything/)
* [ Purge cache by cache-tags ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/)
* [ ​Purge cache by hostname ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-hostname/)
* [ ​Purge cache by prefix (URL) ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge%5Fby%5Fprefix/)
* [ Purge cache key resources ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-cache-key/)
* [ P​urge varied images ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-varied-images/)
* [ Purge zone versions via API ](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-zone-versions/)

Note

If versioning is active on your zone and multiple environments are configured, you can select the specific environment you want to purge. For more details, refer to the [Version Management](https://developers.cloudflare.com/version-management/) documentation.

## Availability and limits

| Free          | Pro                                              | Business                                         | Enterprise                                       |                                                  |
| ------------- | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ |
| Availability  | Yes                                              | Yes                                              | Yes                                              | Yes                                              |
| Purge options | URL, Hostname, Tag, Prefix, and Purge Everything | URL, Hostname, Tag, Prefix, and Purge Everything | URL, Hostname, Tag, Prefix, and Purge Everything | URL, Hostname, Tag, Prefix, and Purge Everything |

### Hostname, tag, prefix URL, and purge everything limits

The current purge limits are applied per **account**:

| Free                       | Pro                   | Business              | Enterprise             |                        |
| -------------------------- | --------------------- | --------------------- | ---------------------- | ---------------------- |
| Requests                   | 5 requests per minute | 5 requests per second | 10 requests per second | 50 requests per second |
| Bucket size                | 25                    | 25                    | 50                     | 500                    |
| Max operations per request | 100                   | 100                   | 100                    | 100                    |

If your account includes zones with different Cloudflare plans, the above limits are shared between all the zones with the same plan. For example, all the zones in your account with a Pro plan will share the limits for the Pro plan, and all the zones in your account with a Business plan will share the limits for the Business plan.

### Single-file purge limits

The current purge limits are applied per **account**:

| Free                       | Pro                 | Business             | Enterprise           |                      |
| -------------------------- | ------------------- | -------------------- | -------------------- | -------------------- |
| URLs                       | 800 URLs per second | 1500 URLs per second | 1500 URLs per second | 3000 URLs per second |
| Max operations per request | 100                 | 100                  | 100                  | 500                  |

If your account includes zones with different Cloudflare plans, the above limits are shared between all the zones with the same plan. For example, all the zones in your account with a Pro plan will share the limits for the Pro plan, and all the zones in your account with a Business plan will share the limits for the Business plan.

Note that the thresholds for URLs are calculated using a moving average.

### Token bucket rate limiting

Cloudflare uses token bucket rate limiting to limit the number of purge requests flowing through the system at any given time, ensuring a steady and manageable flow.

Each account tier has a defined request rate (for example, Free: 5 requests per minute, Business: 10 requests per second), and requests are only allowed if there are available tokens in the bucket. Tokens refill at a consistent rate, but each bucket has a maximum capacity (for example, Free: 25 tokens, Enterprise: 500 tokens), allowing short bursts of requests if tokens have accumulated.

If the bucket is empty, further requests must wait until new tokens are added. This system maintains fair usage while allowing occasional bursts within the bucket's capacity.

If you are an Enterprise customer and you need more operations, reach out to your account team for support.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}}]}
```

---

---
title: ​Purge cache by prefix (URL)
description: You can instantly purge their cache by URL prefix or path separators in their URL. For an example URL like https://www.example.com/foo/bar/baz/qux.jpg, valid purge requests include:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge%5Fby%5Fprefix.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# ​Purge cache by prefix (URL)

You can instantly purge their cache by URL prefix or path separators in their URL. For an example URL like `https://www.example.com/foo/bar/baz/qux.jpg`, valid purge requests include:

* `www.example.com`
* `www.example.com/foo`
* `www.example.com/foo/bar`
* `www.example.com/foo/bar/baz`
* `www.example.com/foo/bar/baz/qux.jpg`

Purging by prefix is useful in different scenarios, such as:

* Purging everything within a directory.
* Increasing control over cached objects in a path.
* Simplifying the number of purge calls sent.
1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Under **Purge Cache**, select **Custom Purge**. The **Custom Purge** window appears.
3. Under **Purge by**, select **Prefix**.
4. Follow the syntax instructions.  
   * One prefix per line.  
   * Maximum 30 prefixes per API call.
5. Enter the appropriate value(s) in the text field using the format shown in the example.
6. Select **Purge**.

For information on rate limits, refer to the [Availability and limits](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits) section.

Warning

If you have a [Transform Rule](https://developers.cloudflare.com/rules/transform/) in place that is modifying part of a URL path, you must use the post-transformed (origin) URL when performing a prefix purge so that purge can take effect.

## Resulting cache status

Purging by prefix deletes the resource, causing `CF-Cache-Status` header to show [MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) for the subsequent request.

If [tiered cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) is used, purging by prefix may return `EXPIRED`, as the lower tier tries to revalidate with the upper tier to reduce load on the latter. Depending on whether the upper tier has the resource or not, and whether the end user is reaching the lower tier or the upper tier, `EXPIRED` or `MISS` are returned.

## Limitations

There are several limitations regarding purge by prefix:

* Path separators are limited to 31 for a prefix `(example.com/a/b/c/d/e/f/g/h/i/j/k/l/m…)`.
* Purge requests are limited to 30 prefixes per request.
* [Purge rate-limits apply](https://developers.cloudflare.com/api/resources/cache/methods/purge/).
* URI query strings & fragments cannot purge by prefix:  
   * `www.example.com/foo?a=b` (query string)  
   * `www.example.com/foo#bar` (fragment)

Warning

Because purge by prefix purges a directory, any URI for a resource within the purged directory is purged regardless of query string or fragment (though fragments are not generally sent by browsers). Purge by prefix rules do not accept fragments and query strings.

Example: If you purge `foo.com/bar`, any asset that starts with `foo.com/bar` will be purged, for example, `foo.com/bar/baz`, `foo.com/bar?good=bad`, etc. and purging `foo.com/bar?good=bad` itself will not work.

## Purge by prefix normalization

Using purge by prefix normalization, when a purge by prefix request comes into Cloudflare for a normalized URL path, the purge service respects the [URL normalization](https://developers.cloudflare.com/rules/normalization/) and purges the normalized URL.

### How does URL Normalization work

Take the following website as an example: `https://cloudflare.com/انشاء-موقع-الكتروني/img_1.jpg`. The table below shows you how Cloudflare’s cache views these paths with [normalization on/off](https://developers.cloudflare.com/rules/normalization/).

| Request from visitor to EDGE                                                                                                                                                                                                                                                                | What Cloudflare cache sees with Normalize Incoming URLs ON                                                                                                                                                                                                                                  | What Cloudflare cache sees with Normalize Incoming URLs OFF                                                                                                                                                                                                                                 | |  [https://cloudflare.com/انشاء-موقع-الكتروني/img\_1.jpg ↗](https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img%5F1.jpg) | [https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img\_1.jpg ↗](https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img%5F1.jpg) | [https://cloudflare.com/انشاء-موقع-الكتروني/img\_1.jpg ↗](https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img%5F1.jpg) |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img\_1.jpg ↗](https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img%5F1.jpg) | [https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img\_1.jpg ↗](https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img%5F1.jpg) | [https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img\_1.jpg ↗](https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img%5F1.jpg) |                                                                                                                                                                                                           |                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                        |
| [https://cloudflare.com/hello/img\_1.jpg ↗](https://cloudflare.com/hello/img%5F1.jpg)                                                                                                                                                                                                       | [https://cloudflare.com/hello/img\_1.jpg ↗](https://cloudflare.com/hello/img%5F1.jpg)                                                                                                                                                                                                       | [https://cloudflare.com/hello/img\_1.jpg ↗](https://cloudflare.com/hello/img%5F1.jpg)                                                                                                                                                                                                       |                                                                                                                                                                                                           |                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                        |

As shown above, with URL normalization **ON**, visitors to the two URLs, `https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img_1.jpg` and `https://cloudflare.com/انشاء-موقع-الكتروني/img_1.jpg`, will be served the same cached asset. Purging `https://cloudflare.com/%D8%A7%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A/img_1.jpg` will instantly purge that asset for both visitors.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge_by_prefix/","name":"​Purge cache by prefix (URL)"}}]}
```

---

---
title: ​Purge cache by hostname
description: Purging by hostname means that all assets at URLs with a host that matches one of the provided values will be instantly purged from the cache.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge-by-hostname.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# ​Purge cache by hostname

Purging by hostname means that all assets at URLs with a host that matches one of the provided values will be instantly purged from the cache.

1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Under **Purge Cache**, select **Custom Purge**. The **Custom Purge** window appears.
3. Under **Purge by**, select **Hostname**.
4. Follow the syntax instructions:  
   * One hostname per line.  
   * Separated by commas.  
   * You can purge up to 30 hostnames at a time.
5. Enter the appropriate value(s) in the text field using the format shown in the example.
6. Select **Purge**.

For information on rate limits, refer to the [Availability and limits](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits) section.

## Resulting cache status

Purging by hostname deletes the resource, resulting in the `CF-Cache-Status` header being set to [MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) for subsequent requests.

If [tiered cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) is used, purging by hostname may return `EXPIRED`, as the lower tier tries to revalidate with the upper tier to reduce load on the latter. Depending on whether the upper tier has the resource or not, and whether the end user is reaching the lower tier or the upper tier, `EXPIRED` or `MISS` are returned.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge-by-hostname/","name":"​Purge cache by hostname"}}]}
```

---

---
title: ​Purge by single-file
description: With purge by single-file, cached resources are instantly removed from the stored assets in your Content Delivery Network (CDN) across all data centers. New requests for the purged asset receive the latest version from your origin web server and add it back to your CDN cache within the specific Cloudflare data center that served the request.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge-by-single-file.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# ​Purge by single-file

With purge by single-file, cached resources are instantly removed from the stored assets in your Content Delivery Network (CDN) across all data centers. New requests for the purged asset receive the latest version from your origin web server and add it back to your CDN cache within the specific Cloudflare data center that served the request.

For information on single-file purge rate limits, refer to the [limits](https://developers.cloudflare.com/cache/how-to/purge-cache/#single-file-purge-limits) section.

A single-file purge performed through your Cloudflare dashboard does not clear objects that contain any of the following:

* [Custom cache keys](https://developers.cloudflare.com/cache/how-to/cache-keys/)
* [Origin header ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Origin)
* Any of these request headers:  
   * `X-Forwarded-Host`  
   * `X-Host`  
   * `X-Forwarded-Scheme`  
   * `X-Original-URL`  
   * `X-Rewrite-URL`  
   * `Forwarded`

You can purge objects with these characteristics using an API call to ([purge files by URL](https://developers.cloudflare.com/api/resources/cache/methods/purge/)). In the data/header section of the API call, you must include all headers and cache keys contained in the cached resource, along with their matching values.

Warning

Always use UTF-8 encoded URLs for single-file cache purges. Wildcards are not supported on single file purge, and you must use purge by hostname, prefix, or implement cache tags as an alternative solution.

1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Under **Purge Cache**, select **Custom Purge**. The **Custom Purge** window appears.
3. Under **Purge by**, select **URL**.
4. Enter the appropriate value(s) in the text field using the format shown in the example. Be aware that the host part of the URL is not case-sensitive, meaning it will always be converted to lowercase according to RFC standards. However, the path portion is case-sensitive. For example, `https://EXAMPLE.com/helloHI` would be treated as `https://example.com/helloHI`.
5. Perform any additional instructions to complete the form.
6. Review your entries.
7. Select **Purge**.

Note

For information on how to use single-file purge to purge assets cached by a Workers fetch, refer to [Single file purge assets cached by a Worker](https://developers.cloudflare.com/workers/reference/how-the-cache-works/#single-file-purge-assets-cached-by-a-worker).

For information on how to purge assets cached by [Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/) operations, refer to [Purge assets stored with the Cache API](https://developers.cloudflare.com/workers/reference/how-the-cache-works/#purge-assets-stored-with-the-cache-api).

Warning

If you have a [Transform Rule](https://developers.cloudflare.com/rules/transform/) in place that is modifying part of a URL path, you must use the non-transform (end user) URL when performing single file purge so that purge can take effect.

## Resulting cache status

Purging by single-file deletes the resource, resulting in the `CF-Cache-Status` header being set to [MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) for subsequent requests.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge-by-single-file/","name":"​Purge by single-file"}}]}
```

---

---
title: Purge cache by cache-tags
description: Cache-tag purging makes multi-file purging easier because you can instantly bulk purge by adding cache-tags to your assets, such as webpages, image files, and more.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge-by-tags.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Purge cache by cache-tags

Cache-tag purging makes multi-file purging easier because you can instantly bulk purge by adding cache-tags to your assets, such as webpages, image files, and more.

## General workflow for cache-tags

1. Add tags to the `Cache-Tag` HTTP response header from your origin web server for your web content, such as pages, static assets, etc.
2. [Ensure your web traffic is proxied](https://developers.cloudflare.com/dns/proxy-status/) through Cloudflare.
3. Cloudflare associates the tags in the `Cache-Tag` HTTP header with the content being cached.
4. Use specific cache-tags to instantly purge your Cloudflare CDN cache of all content containing that cache-tag from your dashboard or [using our API](https://developers.cloudflare.com/api/resources/cache/methods/purge/).
5. Cloudflare forces a [cache MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) on content with the purged cache-tag.

Warning

Be careful when purging. A cache MISS can cause execution delays by requiring a fetch from your origin server.

## Add Cache-Tag HTTP response headers

You add cache-tags to your web content in `Cache-Tag` HTTP response headers to allow the client and server to pass additional information in requests or responses. HTTP headers consist of a specific case-insensitive name followed by a colon `:` and the valid value, for example, `Cache-Tag:tag1,tag2,tag3`. Use commas to separate the tags when you want to use multiple cache-tags.

When your content reaches our edge network, Cloudflare:

* Removes the `Cache-Tag` HTTP header before sending the response to your website visitor or passing the response to a [Worker](https://developers.cloudflare.com/workers/). Your end users or Worker never see `Cache-Tag` HTTP headers on your Cloudflare-enabled website.
* Removes whitespaces from the header and any before and after cache-tag names: `tag1`, `tag2` and `tag1,tag2` are considered the same.
* Removes all repeated and trailing commas before applying cache-tags: `tag1,,,tag2` and `tag1,tag2` are considered the same.

## A few things to remember

* A single HTTP response can have more than one `Cache-Tag` HTTP header field.
* The minimum length of a cache-tag is one byte.
* Individual tags do not have a maximum length, but the aggregate `Cache-Tag` HTTP header cannot exceed 16 KB after the header field name, which is approximately 1,000 unique tags. Length includes whitespace and commas but does not include the header field name.
* For cache purges, the maximum length of a cache-tag in an API call is 1,024 characters.
* The `Cache-Tag` HTTP header must only contain printable ASCII encoded characters.
* Spaces are not allowed in cache-tags.
* Case is not sensitive. For example, `Tag1` and `tag1` are considered the same.

## Purge using cache-tags

1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Under **Purge Cache**, select **Custom Purge**. The **Custom Purge** window appears.
3. Under **Purge by**, select **Tag**.
4. In the text box, enter your tags to use to purge the cached resources. To purge multiple cache-tagged resources, separate each tag with a comma or have one tag per line.
5. Select **Purge**.

For information on rate limits, refer to the [Availability and limits](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits) section.

## Resulting cache status

Purging by tag deletes the resource, resulting in the `CF-Cache-Status` header being set to [MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) for subsequent requests.

If [Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) is used, purging by tag may return `EXPIRED`, as the lower tier tries to revalidate with the upper tier to reduce load on the latter. Depending on whether the upper tier has the resource or not, and whether the end user is reaching the lower tier or the upper tier, `EXPIRED` or `MISS` are returned.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge-by-tags/","name":"Purge cache by cache-tags"}}]}
```

---

---
title: Purge cache key resources
description: Instantly purge resources that use Cache Keys via the Cloudflare API. If you use Cloudflare's Purge by URL, include the headers and query strings that are in your custom Cache Key.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge-cache-key.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Purge cache key resources

Instantly purge resources that use Cache Keys via the [Cloudflare API](https://developers.cloudflare.com/api/resources/cache/methods/purge/). If you use [Cloudflare's Purge by URL](https://developers.cloudflare.com/api/resources/cache/methods/purge/#purge-cached-content-by-url), include the headers and query strings that are in your custom Cache Key.

Currently, it is not possible to purge a URL stored through Cache API that uses a custom cache key set by a Worker. Instead, use a [custom key created by Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#cache-key). Alternatively, purge your assets using purge everything, purge by tag, purge by host or purge by prefix.

To instantly purge by `device_type`, `geo`, or `lang` use `CF-Device-Type`, `CF-IPCountry` or `accept-language`, respectively. [Purge by Tag / Host](https://developers.cloudflare.com/api/resources/cache/methods/purge/#purge-cached-content-by-tag-host-or-prefix) and [Purge Everything](https://developers.cloudflare.com/api/resources/cache/methods/purge/#purge-all-cached-content) are not impacted by the use of custom Cache Keys.

## Purge by device type

For a Cache Key based on device type, purge the asset by passing the `CF-Device-Type` header with the API purge request (valid headers include mobile, desktop, and tablet).

Refer to the example API request below to instantly purge all mobile assets on the root webpage.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Cache Purge`

Purge Cached Content

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "files": [

        {

            "url": "http://my.website.com/",

            "headers": {

                "CF-Device-Type": "mobile"

            }

        }

    ]

  }'


```

## Purge by geo

Instantly purge resources for a location-based Cache Key by specifying the two-letter country code. Spain is used in the example below.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Cache Purge`

Purge Cached Content

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "files": [

        {

            "url": "http://my.website.com/",

            "headers": {

                "CF-IPCountry": "ES"

            }

        }

    ]

  }'


```

## Purge by language

For a Cache Key based on language, purge the asset by passing the `accept-language` header. Refer to the example API request below to instantly purge all assets in Chinese (PRC).

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Cache Purge`

Purge Cached Content

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "files": [

        {

            "url": "http://my.website.com/",

            "headers": {

                "accept-language": "zh-CN"

            }

        }

    ]

  }'


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge-cache-key/","name":"Purge cache key resources"}}]}
```

---

---
title: ​Purge everything
description: To maintain optimal site performance, Cloudflare strongly recommends using single-file (by URL) purging instead of a complete cache purge.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge-everything.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# ​Purge everything

To maintain optimal site performance, Cloudflare strongly recommends using single-file (by URL) purging instead of a complete cache purge.

Purging everything instantly clears all resources from your CDN cache in all Cloudflare data centers. Each new request for a purged resource returns to your origin server to validate the resource. If Cloudflare cannot validate the resource, Cloudflare fetches the latest version from the origin server and replaces the cached version. When a site with heavy traffic contains a lot of assets, requests to your origin server can increase substantially and result in slow site performance.

1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Under **Purge Cache**, select **Purge Everything**. A warning window appears.
3. If you agree, select **Purge Everything**.

Note

When purging everything for a non-production cache environment, all files for that specific cache environment will be purged. However, when purging everything for the production environment, all files will be purged across all environments.

For information on rate limits, refer to the [Availability and limits](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits) section.

## Resulting cache status

Purge Everything invalidates the resource, resulting in the `CF-Cache-Status` header indicating [EXPIRED](https://developers.cloudflare.com/cache/concepts/cache-responses/#expired) for subsequent requests.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge-everything/","name":"​Purge everything"}}]}
```

---

---
title: P​urge varied images
description: Purging varied images instantly purges all content variants for that URL. This behavior occurs so that if an image changes, you can easily update the cache with a single purge request instead of trying to determine the potential number of out-of-date variants. The behavior is true regardless of purge type used, such as single file, tag, or hostname.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge-varied-images.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# P​urge varied images

Purging varied images instantly purges all content variants for that URL. This behavior occurs so that if an image changes, you can easily update the cache with a single purge request instead of trying to determine the potential number of out-of-date variants. The behavior is true regardless of [purge type](https://developers.cloudflare.com/cache/how-to/purge-cache/) used, such as [single file](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/), [tag](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/), or [hostname](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-hostname/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge-varied-images/","name":"P​urge varied images"}}]}
```

---

---
title: Purge zone versions via API
description: To purge zone versions via the Cloudflare API, follow these steps:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/purge-cache/purge-zone-versions.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Purge zone versions via API

To purge zone versions via the Cloudflare API, follow these steps:

## Step 1: Retrieve the environment ID

First, retrieve your zone's environment ID by sending a request to the following API endpoint:

Terminal window

```

https://api.cloudflare.com/client/v4/zones/<zone_id>/environments


```

This API call will return a JSON response similar to the example below:

```

{

  "result": {

    "environments": [

      {

        "name": "Production",

        "ref": "12abcd3e45f678940a573f51834a54",

        "version": 0,

        "expression": "(cf.zone.name eq \"example.com\")",

        "locked_on_deployment": false,

        "position": {

          "before": "5d41402abc4b2a76b9719d911017c"

        }

      },

      {

        "name": "Staging",

        "ref": "5d41402abc4b2a76b9719d911017c",

        "version": 0,

        "expression": "((cf.edge.server_ip in {1.2.3.4 5.6.7.8})) and (cf.zone.name eq \"example.com\")",

        "locked_on_deployment": false,

        "position": {

          "before": "49f0bad299687c62334182178bfd",

          "after": "12abcd3e45f678940a573f51834a54"

        }

      },

      {

        "name": "Development",

        "ref": "49f0bad299687c62334182178bfd",

        "version": 0,

        "expression": "((any(http.request.cookies[\"development\"][*] eq \"true\"))) and (cf.zone.name eq \"example.com\")",

        "locked_on_deployment": false,

        "position": {

          "after": "5d41402abc4b2a76b9719d911017c"

        }

      }

    ]

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

In this particular example, we have three environments: Production, Staging, and Development. You can find the environment ID in the `ref` field.

## Step 2: Purge cache per environment

To purge the Production environment, use the general cache purge endpoint:

Terminal window

```

https://api.cloudflare.com/client/v4/zones/<zone_id>/purge_cache/


```

To purge non-production environments, you must use a new `purge_cache` endpoint and specify the environment you would like to purge.

To purge the Staging environment from the example above, send a request to the following endpoint:

Terminal window

```

https://api.cloudflare.com/client/v4/zones/<zone_id>/environments/5d41402abc4b2a76b9719d911017c/purge_cache/


```

To purge the Development environment from the example above, send a request to the following endpoint:

Terminal window

```

https://api.cloudflare.com/client/v4/zones/<zone_id>/environments/49f0bad299687c62334182178bfd/purge_cache/


```

Note

When purging everything for a non-production cache environment, all files for that specific cache environment will be purged. However, when purging everything for the production environment, all files will be purged across all environments.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/purge-cache/","name":"Purge cache"}},{"@type":"ListItem","position":5,"item":{"@id":"/cache/how-to/purge-cache/purge-zone-versions/","name":"Purge zone versions via API"}}]}
```

---

---
title: Caching levels
description: Caching levels determine how much of your website’s static content Cloudflare should cache. Cloudflare’s CDN caches static content according to the levels below.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/set-caching-levels.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Caching levels

Caching levels determine how much of your website’s static content Cloudflare should cache. Cloudflare’s CDN caches static content according to the levels below.

* **No Query String**: Delivers resources from cache when there is no query string. Example URL: `example.com/pic.jpg`
* **Ignore Query String**: Delivers the same resource to everyone independent of the query string. Example URL: `example.com/pic.jpg?ignore=this-query-string`
* **Standard (Default)**: Delivers a different resource each time the query string changes. Example URL: `example.com/pic.jpg?with=query`

You can adjust the caching level from the dashboard under **Caching** \> **Configuration** \> **Caching level**.

Note

Ignore Query String only disregards the query string for static file extensions. For example, Cloudflare serves the `style.css` resource to requests for either `style.css?this` or `style.css?that`.

## API Caching level values

If you are using the API to change the cache level, the values will differ from those shown in the dashboard. Refer to the table below to see how the API values map to the values shown in the dashboard.

| Dashboard           | API        |
| ------------------- | ---------- |
| No Query String     | Basic      |
| Ignore Query String | Simplified |
| Standard (Default)  | Aggressive |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/set-caching-levels/","name":"Caching levels"}}]}
```

---

---
title: Tiered Cache
description: Tiered Cache uses the size of Cloudflare’s network to reduce requests to customer origins by dramatically increasing cache hit ratios. With data centers around the world, Cloudflare caches content very close to end users. However, if a piece of content is not in cache, the Cloudflare edge data centers must contact the origin server to receive the cacheable content.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/how-to/tiered-cache.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Tiered Cache

Tiered Cache uses the size of Cloudflare’s network to reduce requests to customer origins by dramatically increasing cache hit ratios. With data centers around the world, Cloudflare caches content very close to end users. However, if a piece of content is not in cache, the Cloudflare edge data centers must contact the origin server to receive the cacheable content.

Tiered Cache works by dividing Cloudflare’s data centers into a hierarchy of lower-tiers and upper-tiers. If content is not cached in lower-tier data centers (generally the ones closest to a visitor), the lower-tier must ask an upper-tier to see if it has the content. If the upper-tier does not have the content, only the upper-tier can ask the origin for content. This practice improves bandwidth efficiency by limiting the number of data centers that can ask the origin for content, which reduces origin load and makes websites more cost-effective to operate.

Additionally, Tiered Cache concentrates connections to origin servers so they come from a small number of data centers rather than the full set of network locations. This results in fewer open connections using server resources.

To enable Tiered Cache, refer to [Enable Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/#enable-tiered-cache).

## Tiered Cache Topology

Cloudflare allows you to select your cache topology so that you have control over how your origin connects to Cloudflare’s data centers. This will help ensure higher cache hit ratios, fewer origin connections, and a reduction of Internet latency. Below you can find details about the options we have available.

### Smart Tiered Cache

Smart Shield

This functionality is now offered as part of Cloudflare's origin server safeguard, Smart Shield. [Learn more](https://developers.cloudflare.com/smart-shield/).

Smart Tiered Cache dynamically selects the single closest upper tier for each of your website’s origins with no configuration required, using our in-house performance and routing data. Cloudflare collects latency data for each request to an origin, and uses the latency data to determine how well any upper-tier data center is connected with an origin. As a result, Cloudflare can select the data center with the lowest latency to be the upper-tier for an origin.

#### Load Balancing interaction

While Smart Tiered Cache selects one Upper Tier per origin, when using Load Balancing, Smart Tiered Cache will select the single best Upper Tier for the entire [Load Balancing Pool](https://developers.cloudflare.com/load-balancing/understand-basics/load-balancing-components/#pools).

#### Caveats

Smart Tiered Cache does not work when an origin is behind an [anycast ↗](https://www.cloudflare.com/en-gb/learning/cdn/glossary/anycast-network/) or a regional unicast network because that will prevent us from knowing where the origin is located. As a result, we are unable to select the optimal upper tier and latency may be negatively impacted.

You need to be careful when updating your origin IPs/DNS records while Smart Tiered Cache is enabled. Depending on the changes made, it may cause the existing assigned upper tiers to change, resulting in an increased `MISS` rate as cache is refilled in the new upper tiers. If the origin is switched to a network behind anycast, it will significantly reduce the effectiveness of Smart Tiered Cache.

If you need to use anycast or regional unicast and want to use Smart Tiered cache, please engage your account team.

### Generic Global Tiered Cache

Generic Global topology allows for all of Cloudflare’s global data centers to serve as a network of upper-tiers. This topology may help reduce the long tail latencies for far-away visitors.

### Regional Tiered Cache

Smart Shield

This functionality is now offered as part of Cloudflare's origin server safeguard, Smart Shield. [Learn more](https://developers.cloudflare.com/smart-shield/).

Regional Tiered Cache provides an additional layer of caching for customers who have a global traffic footprint and want to serve content faster by avoiding network latency when there is a cache `MISS` in a lower-tier, resulting in an upper-tier fetch in a data center located far away.

Regional Tiered Cache instructs Cloudflare to check a regional hub data center near the lower tier before going to the upper tier that may be outside of the region.

This can help improve performance for **Smart** and **Custom Tiered Cache** topologies with upper-tiers in one or two regions. Regional Tiered Cache is not beneficial for customers with many upper tiers in many regions like Generic Global Tiered Cache.

### Custom Tiered Cache

Custom Tiered cache allows Enterprise customers to work with their account team to set a custom topology that fits your specific needs, for instance you have close upper tiers or you have an unique traffic pattern. If you want a custom topology, please engage your account team.

## Availability

| Free                    | Pro | Business | Enterprise |     |
| ----------------------- | --- | -------- | ---------- | --- |
| Tiered Cache            | Yes | Yes      | Yes        | Yes |
| Smart Topology          | Yes | Yes      | Yes        | Yes |
| Generic Global Topology | No  | No       | No         | Yes |
| Regional Tiered Cache   | No  | No       | No         | Yes |
| Custom Topology         | No  | No       | No         | Yes |

## Bandwidth Alliance

Enterprise customers can override Bandwidth Alliance configuration with Tiered Cache. For all other users, the Bandwidth Alliance takes precedence. Tiered Cache is still a valuable option to enable because the Bandwidth Alliance may not always be an available option, and in those instances, the Tiered Cache configuration will be used.

## Enable Tiered Cache

You can enable Tiered Cache in the dashboard or via API.

### Enable Tiered Cache in the dashboard

1. In the Cloudflare dashboard, go to the **Tiered Cache** page.  
[ Go to **Tiered Cache** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/tiered-cache)
2. From **Tiered Cache**, toggle the button to **enabled**.
3. In **Tiered Cache Topology**, you can control how your origin connects to Cloudflare’s data centers. You can select:  
   * **Upper Tier Cache** \- You have the option to choose between Smart or Generic Global Tiered Cache Topology.  
   * **Middle Tier Cache** \- If you have selected Smart or Custom Tiered Cache Topology, you can now enable Regional Tiered Cache.  
   * **Custom Tiered Cache** \- Allows you to work with Cloudflare’s support team to set a custom topology that fits your specific needs.  
   * **Disable Tiered Cache**.
![Tiered Cache Topology dashboard](https://developers.cloudflare.com/_astro/tiered_cache_topology.sy3gfwwc_Z1XYoHF.webp) 

### Enable Tiered Cache via API

To enable Tiered Cache via API use the following cURL example:

Patch Tiered Caching setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/argo/tiered_caching" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "value": "on"

  }'


```

You can also configure Tiered Cache Topology via API, for instance:

Enable Smart Tiered Cache

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Write`

Patch Smart Tiered Cache setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/tiered_cache_smart_topology_enable" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "value": "on"

  }'


```

Enable Regional Tiered Cache

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Zone Settings Write`
* `Zone Write`

Change Regional Tiered Cache setting

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/regional_tiered_cache" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "value": "on"

  }'


```

For more API examples and configuration options for Tiered Cache, refer to the [API documentation](https://developers.cloudflare.com/api/resources/argo/subresources/tiered%5Fcaching/methods/get/).

Note

To confirm that Tiered Cache is working, make sure you have the value of `[CacheTieredFill](/logs/logpush/logpush-job/datasets/zone/http_requests/#cachetieredfill)` in your http\_requests logs, this will indicate if Tiered Cache was used to serve the request.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/how-to/","name":"Cache configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/how-to/tiered-cache/","name":"Tiered Cache"}}]}
```

---

---
title: Enable cache in an R2 bucket
description: To enable caching for a Cloudflare R2 bucket, make sure your bucket is public and accessible by the Cache. This can be done by creating a Custom Domain. Follow these steps to set up a Custom Domain for your bucket:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/interaction-cloudflare-products/r2.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Enable cache in an R2 bucket

To enable caching for a [Cloudflare R2](https://developers.cloudflare.com/r2/) bucket, make sure your bucket is public and accessible by the Cache. This can be done by creating a [Custom Domain](https://developers.cloudflare.com/r2/buckets/public-buckets/#custom-domains). Follow these steps to set up a Custom Domain for your bucket:

1. Go to **R2** and select your bucket.
2. On the bucket page, select **Settings**.
3. Under **Public access** \> **Custom Domains**, select **Connect Domain**.
4. Enter the domain name you want to connect to and select **Continue**.
5. Review the new record that will be added to the DNS table and select **Connect Domain**.

This will generate a publicly available CNAME in the format `[name].domain.com`.

## Tiered Cache

By default Cloudflare will cache R2 content based on [cache rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) at the Edge only.

Tiered cache can be enabled by configuring [Smart Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/#smart-tiered-cache) which will select an Upper Tier data center next to your R2 bucket for optimal performance.

## Additional considerations

* Apply access controls to your newly public bucket. Refer to [Control cache access with WAF and Snippets](https://developers.cloudflare.com/cache/interaction-cloudflare-products/waf-snippets/) for more information.
* Be aware of the [cacheable size limits](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#cacheable-size-limits) for files.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/interaction-cloudflare-products/","name":"Interaction with Cloudflare products"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/interaction-cloudflare-products/r2/","name":"Enable cache in an R2 bucket"}}]}
```

---

---
title: Control cache access with WAF and Snippets
description: To limit access to the public bucket created for caching content, you can use Cloudflare's WAF. The WAF provides an additional security layer to filter requests and ensure that only authorized traffic reaches your bucket.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/interaction-cloudflare-products/waf-snippets.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Control cache access with WAF and Snippets

To limit access to the public bucket created for caching content, you can use Cloudflare's [WAF](https://developers.cloudflare.com/waf/custom-rules/use-cases/configure-token-authentication/). The WAF provides an additional security layer to filter requests and ensure that only authorized traffic reaches your bucket.

The following diagram illustrates the flow of a user's request through WAF, Cache, and R2.

flowchart LR
accTitle: Connections with Cloudflare
A[User's request] --> B[WAF] --> C[Cache] --> D[R2]

  
The WAF product uses token authentication to either sign or authenticate a request. You can then use this in either Workers or Snippets to control access.

## Presigned URLs

You can presign URLs similar to [S3 ↗](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html), enabling you to share direct access to your content with a with an associated timeout. This approach can be implemented using a combination of Snippets, Rules, or Cloudflare Workers.

For optimal performance, we recommend separating the creation and validation processes as follows:

* [Snippets](https://developers.cloudflare.com/rules/snippets/examples/signing-requests/) for HMAC creation
* [Rules](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#hmac-validation) for HMAC validation

In the Workers documentation, in the section [Signing requests](https://developers.cloudflare.com/workers/examples/signing-requests/), you can also find an example of how to verify a signed request using the HMAC.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/interaction-cloudflare-products/","name":"Interaction with Cloudflare products"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/interaction-cloudflare-products/waf-snippets/","name":"Control cache access with WAF and Snippets"}}]}
```

---

---
title: Customize cache behavior with Workers
description: You can use Workers to customize cache behavior on Cloudflare's CDN. Cloudflare Workers provide flexibility in handling assets and responses by running both before and after the cache. A Worker can be configured to run before a request reaches the cache, allowing for modifications to the request, and it can also be used to modify assets once they are returned from the cache.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/interaction-cloudflare-products/workers.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Customize cache behavior with Workers

You can use [Workers](https://developers.cloudflare.com/workers/) to customize cache behavior on Cloudflare's CDN. Cloudflare Workers provide flexibility in handling assets and responses by running both before and after the cache. A Worker can be configured to run before a request reaches the cache, allowing for modifications to the request, and it can also be used to modify assets once they are returned from the cache.

The diagram below illustrates a common interaction flow between Workers and Cache.

![Workers and cache flow example flow diagram.](https://developers.cloudflare.com/_astro/workers-cache-flow.DBEQRofC_ZP2BOU.webp) 
1. A User (a) Requests a URI, and this request is directed to a Worker. The Worker can then interact with the request, either requesting the content further upstream using (b) fetch() or sending a (f) Response back to the User.
2. If the content is cached, the Cache will send a (e) Response back to the Worker which can now interact with the response before sending a (f) Response back to the user.
3. When using cache rules with Workers, the cache rule should not be set based on the user URL/host (a). Instead, the rule must match the properties of the URL in the fetch() (b) request — such as headers, hostname, or URL path — otherwise, the rule will not be applied.

Here are a few examples of how Workers can be used to customize cache behavior:

* **Modify Response**: Adjust or enhance content after it is retrieved from the cache, ensuring that responses are up-to-date or tailored to specific needs.
* **Signed URLs**: Generate URLs that are valid for a specific duration (for example, minutes, hours, days) to control access and enhance security.
* **Personalized Response**: Deliver personalized content based on user data while leveraging cached resources to reduce the load on the origin.
* **Reduce Latency**: Serve content from a location close to the user, decreasing load times and improving the user experience.

You can also use [Snippets](https://developers.cloudflare.com/rules/snippets/) as a free alternative for simple modifications and logic, bypassing the need for full Worker scripts. These lightweight scripts enable quick adjustments and optimizations, offering an efficient way to enhance your Cloudflare setup without the complexity and overhead of more extensive code deployments.

Note

When using Workers and [O2O](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/saas-customers/how-it-works/), some caveats and limitations may apply.

## Cache features in Workers

* **fetch()**: Allows interaction with Cloudflare's Cache and Tiered Cache, providing control over how requests are handled. To optimize caching behavior, you can set TTLs, define custom cache keys, and configure cache headers directly within a fetch request. For more details on these configurations, refer to [Cache using fetch](https://developers.cloudflare.com/workers/examples/cache-using-fetch/).
* **Cache API**: Enables storing and retrieving responses from Cloudflare's cache, limited to the cache in the local data center and excluding content stored in the Tiered Cache. To use the Cache API to store responses in Cloudflare's cache, refer to [Using the Cache API](https://developers.cloudflare.com/workers/examples/cache-api/).

To understand more about how Cache and Workers interact refer to [Cache in Workers](https://developers.cloudflare.com/workers/reference/how-the-cache-works/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/interaction-cloudflare-products/","name":"Interaction with Cloudflare products"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/interaction-cloudflare-products/workers/","name":"Customize cache behavior with Workers"}}]}
```

---

---
title: How Workers interact with Cache Rules
description: Your Workers script can override Cache Rules behavior, whether it is applied to a zone using Cloudflare or a zone that is not proxied through Cloudflare.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/interaction-cloudflare-products/workers-cache-rules.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# How Workers interact with Cache Rules

Your Workers script can override [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) behavior, whether it is applied to a zone using Cloudflare or a zone that is not proxied through Cloudflare.

For example, if there is a cache rule configured to bypass cache for `example.com/foo`, but your Workers script sets `cacheEverything: true`, the script's setting will take precedence, and the request will be cached. The same applies if the request is made to a non-Cloudflare zone — the Worker's `cacheEverything` setting will still override.

## Precedence order

Cache behavior is determined by the following order of precedence:

1. [Workers](https://developers.cloudflare.com/workers/) script settings
2. [Cache rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
3. [Page rules](https://developers.cloudflare.com/rules/page-rules/)

Cache rules override page rule settings, and Workers scripts override cache rules. Among rules at the same level, the one with the highest specificity takes priority.

## Compatibility flags

This override behavior is controlled by [compatibility flags](https://developers.cloudflare.com/workers/configuration/compatibility-flags/):

* For the [Fetch API](https://developers.cloudflare.com/workers/runtime-apis/fetch/): `request_cf_overrides_cache_rules`
* For the [Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/): `cache_api_request_cf_overrides_cache_rules`

These flags must be enabled to allow Workers scripts to override cache rules.

### Compatibility date behavior

Whether these flags are enabled by default depends on your Worker's compatibility date:

* **Fetch API (`request_cf_overrides_cache_rules`)**  
   * Enabled by default for compatibility dates **on or after 2025-04-02**.
* **Cache API (`cache_api_request_cf_overrides_cache_rules`)**  
   * Enabled by default for compatibility dates **on or after 2025-05-19**.  
   * **Important:** For `cache_api_request_cf_overrides_cache_rules` to be recognized, you must also enable `cache_api_compat_flags`.  
         * `cache_api_compat_flags` enables the compatibility flag functionality for Workers. If `cache_api_compat_flags` is not set, then no compatibility flags — even if configured — will be recognized by the Cache API.  
         * `cache_api_compat_flags` is enabled by default for compatibility dates **on or after 2025-04-19**.

If your Worker has an earlier compatibility date than the ones listed above, the corresponding flags must be manually enabled; otherwise, cache behavior will follow the original cache rules instead of the Worker's settings.

### Example (Older compatibility date)

If a cache rule is configured to bypass cache for `example.com/foo`, and a Worker with a compatibility date of `2025-04-02` or earlier tries to set `cacheEverything: true`, the cache rule will take effect, and the response will not be cached.

Likewise, if using the Cache API without `cache_api_compat_flags` enabled, even if you enable `cache_api_request_cf_overrides_cache_rules`, the Cache API will not take effect.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/interaction-cloudflare-products/","name":"Interaction with Cloudflare products"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/interaction-cloudflare-products/workers-cache-rules/","name":"How Workers interact with Cache Rules"}}]}
```

---

---
title: Cache Analytics
description: Use Cache Analytics to improve site performance or reduce origin web server traffic. Cache Analytics helps determine if resources are missing from cache, expired, or ineligible for caching. Cache Analytics includes filter by hostname, list of top URLs that miss cache, and a query of up to three days of data.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/performance-review/cache-analytics.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Analytics

Use Cache Analytics to improve site performance or reduce origin web server traffic. Cache Analytics helps determine if resources are [missing from cache](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss), [expired](https://developers.cloudflare.com/cache/concepts/cache-responses/#expired), or [ineligible for caching](https://developers.cloudflare.com/cache/concepts/cache-responses/#noneunknown). Cache Analytics includes filter by hostname, list of top URLs that miss cache, and a query of up to three days of data.

## Availability

| Free             | Pro | Business | Enterprise |         |
| ---------------- | --- | -------- | ---------- | ------- |
| Availability     | No  | Yes      | Yes        | Yes     |
| Retention period | N/A | 7 days   | 30 days    | 30 days |

## Access Cache Analytics

In the Cloudflare dashboard, go to the **Caching** page.

[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/caching) 

## Requests vs Data Transfer

You can decide wheter to focus on **Requests** or **Data Transfer**:

* **Requests** (default view) help assess performance, as each cache [MISS](https://developers.cloudflare.com/cache/concepts/cache-responses/#miss) slows down content delivery.
* **Data Transfer** is useful for cost analysis, since most hosting providers charge for every byte that leaves their network.

You can switch between these views while keeping other analytics filters applied.

For best practices related to Cache Analytics, refer to [Cache performance](https://developers.cloudflare.com/cache/performance-review/cache-performance/).

## Add filters

Cache Analytics also allows for flexible filtering of data. Create filters to focus on the traffic to optimize. Example filters include **Cache status**, **Host**, **Path**, or **Content type**.

To add filters, under **Cache Performance**, select **Add filter**. Select **Apply** when you are done.

## Review cache status

The **Requests summary** graph depicts how your traffic changes over time, such as in response to a high-traffic event or a recent configuration change. Note that the Requests summary content is based on a 10% sample of requests. For more information on how sampling works, refer to [Understanding sampling in Cloudflare Analytics](https://developers.cloudflare.com/analytics/sampling/).

**Served by Cloudflare** indicates content served by Cloudflare that did not require contacting your origin web server. **Served by Origin** indicates traffic served from the origin web server.

For **Data Transfer**, **Revalidated** requests are considered **Served by Cloudflare**. However, revalidated requests count as **Served by Origin** within the **Requests** view. This analytics behavior reflects that Cloudflare must check the origin web server for revalidated cache requests before returning a result from cache.

**Cache status** graphs help explain why traffic is served from Cloudflare versus the origin web server. The graph shows analytics by content-type to portray how different components of your website perform:

For a breakdown of cache statuses and their descriptions, refer to [Cloudflare cache responses](https://developers.cloudflare.com/cache/concepts/cache-responses/).

## Review requests by source

Cache Analytics shows top metrics (Top-N) for several request components. Apply filters before reviewing Top-N metrics. For example, filtering to only view traffic with an Expired or Revalidated Cache status lets you review which URLs were primarily responsible for those statuses.

### Empty content types

Finding an **empty** content type when reviewing your analytics is common. This content type occurs when 301/302 redirects do not contain an HTTP response body. Additionally, most HTTP error codes, such as 403, do not return text/html and are therefore also reported as empty.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/performance-review/","name":"Performance review"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/performance-review/cache-analytics/","name":"Cache Analytics"}}]}
```

---

---
title: Cache performance
description: Depending on the cache status you receive, you can make modifications to improve your cache ratio. To review the list of cache statuses, refer to Cloudflare cache responses.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/performance-review/cache-performance.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache performance

## Optimize cache ratios

Depending on the cache status you receive, you can make modifications to improve your cache ratio. To review the list of cache statuses, refer to [Cloudflare cache responses](https://developers.cloudflare.com/cache/concepts/cache-responses/).

* **Dynamic**: Default response for many file types including HTML. To cache additional content, refer to [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/).
* **Revalidated**: To address an atypical quantity of revalidated content, consider [increasing your Edge Cache TTLs](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl).
* **Expired**: Consider [extending Edge Cache TTLs](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl)) for these resources via a Cache Rule or enable revalidation at your origin.
* **Miss**: Although tricky to optimize, there are a few potential remedies:  
   * [Enable Argo Tiered Caching](https://developers.cloudflare.com/cache/how-to/tiered-cache/#enable-tiered-cache) to check cache in another Cloudflare data center before checking the origin web server.  
   * [Create a custom cache key](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/custom-cache-key/) for multiple URLs to match the same cached resource, for example by ignoring query string.

## Example reports for troubleshooting cache performance

Several examples of helpful insights into your site performance via Cache Analytics include:

* Not caching HTML.  
   * Identify the issue: Select **Add filter** and select **Cache status equals Dynamic**.  
   * Resolution: Set a Cloudflare Cache Rule to [cache dynamic content](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/cache-everything/).

Warning

This option caches all HTML regardless of the presence of dynamic content. If you use this approach to cache pages containing dynamic content, visitors may receive information not intended for them. To avoid caching dynamic content, you can add a condition to the rule's matching criteria to prevent it from matching that content. Some examples include:

* Checking for the presence of a cookie.
* Negative matching against known dynamic content file paths.
* Negative matching against dynamic content extensions (or lack of an extension).

* Short cache expiration TTL.  
   * Identify the issue: Select **Add filter** and select **Cache status equals Revalidated**.  
   * Resolution: [Increase Cloudflare's Edge Cache TTL via a Cache Rule](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/edge-ttl/).
* Need to enable Tiered Cache or Custom Cache Key  
   * Identify the issue: Select **Add filter** and select **Cache status equals Miss**.  
   * Resolution: [Enable Argo Tiered Caching](https://developers.cloudflare.com/cache/how-to/tiered-cache/#enable-tiered-cache) or [create a custom cache key](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/custom-cache-key/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/performance-review/","name":"Performance review"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/performance-review/cache-performance/","name":"Cache performance"}}]}
```

---

---
title: CDN Reference Architecture
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/reference/cdn-reference-architecture.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# CDN Reference Architecture

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/reference/","name":"Reference"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/reference/cdn-reference-architecture/","name":"CDN Reference Architecture"}}]}
```

---

---
title: CSAM Scanning Tool
description: The Child Sexual Abuse Material (CSAM) Scanning Tool allows website owners to proactively identify and take action on CSAM located on their website. By enabling this tool, Cloudflare will compare content served for your website through the Cloudflare cache to known lists of CSAM. These lists are provided to Cloudflare by leading child safety advocacy groups such as the National Center for Missing and Exploited Children (NCMEC).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/reference/csam-scanning.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# CSAM Scanning Tool

The Child Sexual Abuse Material (CSAM) Scanning Tool allows website owners to proactively identify and take action on CSAM located on their website. By enabling this tool, Cloudflare will compare content served for your website through the Cloudflare cache to known lists of CSAM. These lists are provided to Cloudflare by leading child safety advocacy groups such as the National Center for Missing and Exploited Children (NCMEC).

Remember, by enabling the Service, you agree to the [Service-Specific Terms ↗](https://www.cloudflare.com/service-specific-terms-application-services/#csam-scanning-tool-terms) for the CSAM Scanning Tool. You agree to use this tool solely for the purposes of preventing the spread of CSAM.

---

## Why would a URL be blocked?

Because knowingly distributing or viewing CSAM is illegal, the owner of the website has enabled Cloudflare's CSAM scanning tool to proactively identify and block images identified as CSAM located on their website.

---

## Configure the CSAM scanning tool

To enable the tool:

1. Log into the [Cloudflare dashboard ↗](https://dash.cloudflare.com/).
2. Select your account and zone.
3. Go to **Caching** \> **Configuration**.
4. For **CSAM Scanning Tool**, select **Configure**.

You must provide an email address, which will be used to notify you in the event Cloudflare detects a positive match.

---

## What happens when a match is detected?

When a potential match is detected with the tool:

1. An email is sent to you once per day to inform you of any detections made in the past 24 hours. This email will include the file paths of any content that was matched.
2. If possible, a block is placed to prevent further serving of the matched content. If a block fails, we will indicate that the content has not been blocked in the email.

---

## What action should I take when a match is detected?

You are responsible for understanding and complying with any legal obligations you have as a website owner when made aware of any potential CSAM. Although legal obligations vary based on the provider and the jurisdiction, website owners often have obligations to report apparent CSAM, to remove content, and to preserve records. Some of those possible obligations are as follows:

* You likely have an obligation to report apparent CSAM to the appropriate authorities. You can file a report to NCMEC with additional information via NCMEC's CyberTip reporting form or find the preferred reporting portal for your jurisdiction via the INHOPE website.
  
* You may need to preserve and securely store a copy of the content and related data in the case NCMEC or law enforcement reach out for additional details.
* You likely have an obligation to securely preserve certain information related to your report for at least 90 days in the case of an investigation. To ensure that access to the content is limited, take care not to store this information anywhere accessible to anyone but those within your organization responsible for legal requests.
  
* You should remove the content and notify Cloudflare of the removal.
* Once any preservation obligations have been fulfilled, you should remove the content from your website. This is especially important if Cloudflare's notice to you indicates that our block was unsuccessful.

---

## How do I have a block removed from my website?

To disable a block, either because you have determined that the blocked content is not CSAM (a false positive) or because you have taken down the blocked content, view [Blocked Content in the Security Center](https://developers.cloudflare.com/security-center/blocked-content/) in the Cloudflare Dashboard and request reviews on the relevant blocks. A request to remove a block must be accompanied by a representation from you confirming that the blocked content is not CSAM or has been removed.

These actions are available to users with the following roles:

* Admin
* Super Admin
* Trust & Safety

---

## Additional Resources

[CSAM Scanning Tool Supplemental Terms ↗](https://www.cloudflare.com/supplemental-terms/)

[National Center for Missing and Exploited Children (NCMEC) ↗](https://www.missingkids.org/)

[NCMEC CyberTipline ↗](https://www.missingkids.org/gethelpnow/cybertipline)

[INHOPE ↗](https://www.inhope.org/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/reference/","name":"Reference"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/reference/csam-scanning/","name":"CSAM Scanning Tool"}}]}
```

---

---
title: Development Mode
description: Development Mode temporarily suspends Cloudflare's edge caching and Polish features for three hours unless disabled beforehand. Development Mode allows customers to immediately observe changes to their cacheable content like images, CSS, or JavaScript.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/reference/development-mode.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Development Mode

Development Mode temporarily suspends Cloudflare's edge caching and [Polish](https://developers.cloudflare.com/images/polish/) features for three hours unless disabled beforehand. Development Mode allows customers to immediately observe changes to their [cacheable content](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions) like images, CSS, or JavaScript.

Note

To bypass cache for longer than three hours, use bypass cache in [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#bypass-cache).

## Enable Development Mode

Development Mode temporarily bypasses Cloudflare's cache and does not purge cached files. To instantly purge your Cloudflare cache, refer to [purge cache](https://developers.cloudflare.com/cache/how-to/purge-cache/).

1. In the Cloudflare dashboard, go to the **Configuration** page.  
[ Go to **Configuration** ](https://dash.cloudflare.com/?to=/:account/:zone/caching/configuration)
2. Toggle **Development Mode** to **On**.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/reference/","name":"Reference"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/reference/development-mode/","name":"Development Mode"}}]}
```

---

---
title: Using ETag Headers with Cloudflare
description: ETag headers identify whether the version of a resource cached in the browser is the same as the resource at the origin web server. A visitor's browser stores ETags. When a visitor revisits a site, the browser compares each ETag to the one it stored. Matching values cause a 304 Not-Modified HTTP response that indicates the cached resource version is current. Cloudflare supports both strong and weak ETags configured at your origin web server.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/reference/etag-headers.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Using ETag Headers with Cloudflare

ETag headers identify whether the version of a resource cached in the browser is the same as the resource at the origin web server. A visitor's browser stores ETags. When a visitor revisits a site, the browser compares each ETag to the one it stored. Matching values cause a `304 Not-Modified HTTP` response that indicates the cached resource version is current. Cloudflare supports both strong and weak ETags configured at your origin web server.

## Weak ETags

Weak ETag headers indicate a cached resource is semantically equivalent to the version on the web server but not necessarily byte-for-byte identical.

Note

When using weak ETag headers, it is necessary to disable certain features such as [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/) and [Automatic HTTPS Rewrites](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/automatic-https-rewrites/) to prevent Cloudflare from removing the ETag headers set by your origin web server. For a comprehensive list of the features you need to disable, refer to the [Notes about end-to-end compression](https://developers.cloudflare.com/speed/optimization/content/compression/#notes-about-end-to-end-compression).

## Strong ETags

Strong ETag headers ensure the resource in browser cache and on the web server are byte-for-byte identical. Use [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) to enable strong ETag headers.

### Behavior with Respect Strong ETags enabled

When you enable **Respect Strong ETags** in a cache rule, Cloudflare will use strong ETag header validation to ensure that resources in the Cloudflare cache and on the origin server are byte-for-byte identical.

However, in some situations Cloudflare will convert strong ETags to weak ETags. For example, given the following conditions:

* **Respect Strong ETags** is enabled
* [Brotli compression](https://developers.cloudflare.com/speed/optimization/content/compression/) is enabled
* The origin server's response includes an `etag: "foobar"` strong ETag header

The Cloudflare network will take the following actions, depending on the visitor's `accept-encoding` header and the compression used in the origin server's response:

| accept-encodingheader from visitor | Compression used in origin server response | Cloudflare actions                                                                                     |
| ---------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
| gzip, br                           | GZIP                                       | Return GZIP-compressed response to visitor with strong ETag header: etag: "foobar".                    |
| gzip, br                           | Brotli                                     | Return Brotli-compressed response to visitor with strong ETag header: etag: "foobar".                  |
| br                                 | GZIP                                       | Decompress GZIP and return uncompressed response to visitor with weak ETag header: etag: W/"foobar".   |
| gzip                               | Brotli                                     | Decompress Brotli and return uncompressed response to visitor with weak ETag header: etag: W/"foobar". |
| gzip                               | (none)                                     | Return uncompressed response to visitor with strong ETag header: etag: "foobar".                       |
| gzip, br, zstd                     | Zstandard                                  | Return zstd-compressed response to visitor with strong ETag header: etag: "foobar".                    |
| gzip, br                           | Zstandard                                  | Decompress zstd and return br response to visitor with weak ETag header: etag: W/"foobar".             |
| zstd                               | Brotli/GZIP                                | Decompress zstd and return zstd response to visitor with weak ETag header: etag: W/"foobar".           |

Enabling **Respect Strong ETags** in Cloudflare automatically disables Rocket Loader, Email Obfuscation, and Automatic HTTPS Rewrites.

### Behavior with Respect Strong ETags disabled

When **Respect Strong ETags** is disabled, Cloudflare will preserve strong ETag headers set by the origin web server if all the following conditions apply:

* The origin server sends a response compressed using GZIP or Brotli, or an uncompressed response.
* If the origin server sends a compressed response, the visitor accepts the same compression (GZIP, Brotli), according to the `accept-encoding` header.
* [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/) and [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/) features are disabled.

In all other situations, Cloudflare will either convert strong ETag headers to weak ETag headers or remove the strong ETag. For example, given the following conditions:

* **Respect Strong ETags** is disabled
* [Brotli compression](https://developers.cloudflare.com/speed/optimization/content/compression/) is enabled
* The origin server's response includes an `etag: "foobar"` strong ETag header

The Cloudflare network will take the following actions, depending on the visitor's `accept-encoding` header and the compression used in the origin server's response:

| accept-encodingheader from visitor | Compression used in origin server response | Cloudflare actions                                                                                                                              |
| ---------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| gzip, br                           | GZIP                                       | Decompress GZIP and return Brotli-compressed response to visitor (since Brotli compression is enabled) with weak ETag header: etag: W/"foobar". |
| gzip, br                           | Brotli                                     | Return Brotli-compressed response to visitor with strong ETag header: etag: "foobar".                                                           |
| br                                 | GZIP                                       | Decompress GZIP and return Brotli-compressed response to visitor with weak ETag header: etag: W/"foobar".                                       |
| gzip                               | Brotli                                     | Decompress Brotli and return GZIP-compressed response to visitor with weak ETag header: etag: W/"foobar".                                       |
| gzip                               | (none)                                     | Compress origin response using GZIP and return it to visitor with weak ETag header: etag: W/"foobar".                                           |
| gzip, br, zstd                     | Zstandard                                  | Return zstd-compressed response to visitor with strong ETag header: etag: "foobar".                                                             |
| gzip, br                           | Zstandard                                  | Decompress zstd and return uncompressed response to visitor with weak ETag header: etag: W/"foobar".                                            |
| zstd                               | Brotli                                     | Decompress zstd and return uncompressed response to visitor with weak ETag header: etag: W/"foobar".                                            |

Refer to [Content compression](https://developers.cloudflare.com/speed/optimization/content/compression/) for more information.

## Important remarks

* You must set the value in a strong ETag header using double quotes (for example, `etag: "foobar"`). If you use an incorrect format, Cloudflare will remove the ETag header instead of converting it to a weak ETag.
* If a resource is cacheable and there is a cache miss, Cloudflare does not send ETag headers to the origin server. This is because Cloudflare requires the full response body to fill its cache.
* If your origin (or R2) applies compression based on `accept-encoding`, the first compression type will be cached. Consider whether strong ETags fit your use case, or use cache key rules to handle different compression types.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/reference/","name":"Reference"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/reference/etag-headers/","name":"Using ETag Headers with Cloudflare"}}]}
```

---

---
title: Always Online
description: Observe the following best practices when enabling Always Online with Internet Archive integration.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/cache/troubleshooting/always-online.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Always Online

Observe the following best practices when enabling Always Online with Internet Archive integration.

* **Allow requests from the Internet Archive IP addresses.** Origin servers receive requests from the Internet Archive IPs. Make sure you are not blocking requests from the Internet Archive IP range: `207.241.224.0/20` and `208.70.24.0/21`.
* **The Internet Archive does not consider your origin server's cache-control header.** When the Internet Archive is crawling sites, it will crawl sites regardless of their cache-control, since the Internet Archive does not cache assets, but archives them.
* **Consider potential conflicts with Cloudflare features that transform URIs.** Always Online with Internet Archive integration may cause issues with Cache Rules and other Cloudflare features that transform URIs due to the way the Internet Archive crawls pages to archive. Specifically, some redirects that take place at the edge may cause the Internet Archive's crawler not to archive the target URL. Before enabling Origin Cache Control, review [how Cloudflare caches resources by default](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/) as well as any Cache Rules you have configured so that you can avoid these issues. If you experience problems, disable Always Online.
* **Do not block Known Bots or Verified Bots via a WAF custom rule.** If you block either of these bot lists, the Internet Archive will not be able to crawl.

Do not use Always Online with:

* API traffic.
* An [IP Access rule](https://developers.cloudflare.com/waf/tools/ip-access-rules/) or a [WAF custom rule](https://developers.cloudflare.com/waf/custom-rules/) that blocks the United States or
* Bypass Cache cache rules. Always Online ignores Bypass Cache cache rules and serves Always Online cached assets.

## Limitations

There are limitations with the Always Online functionality:

1. Always Online is not immediately active for sites recently added due to:  
   * DNS record propagation, which can take 24-72 hours  
   * Always Online has not initially crawled the website
2. Cloudflare cannot show private content behind logins or handle form submission (POSTs) if your origin web server is offline.

Always Online does not trigger for HTTP response codes such as [404](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/4xx-client-error/error-404/), [503](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-503/), or [500](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-500/) errors such as database connection errors or internal server errors.

## Frequently asked questions

1. How can I know if a page has been crawled?  
   * You can go to the [Internet Archive ↗](https://web.archive.org/) and search for the page URL to see if it has been crawled or not.  
   * You can also check this via the [Internet Archive Availability API ↗](https://archive.org/help/wayback%5Fapi.php).
2. Why were not pages x, y, and z crawled?  
   * Since Cloudflare only requests to crawl the most popular pages on the site, it is possible that there will be missing pages. If you really want to archive a page, then you can visit the [Internet Archive ↗](https://web.archive.org/save) save page and ask them to crawl a particular page.
3. What IP addresses do we need to allowlist to make sure crawling works?  
   * IP Range: `207.241.224.0/20` and `208.70.24.0/21`. Note that this ip range belongs to Internet Archive and NOT Cloudflare, since it is the Internet Archive that does the crawling.
4. What user agent should the origin expect to see?  
   * Currently the Internet Archive uses: `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/605.1.15`.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cache/","name":"Cache / CDN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cache/troubleshooting/","name":"Troubleshooting"}},{"@type":"ListItem","position":4,"item":{"@id":"/cache/troubleshooting/always-online/","name":"Always Online"}}]}
```
