Skip to content

[Cache] SEO: cache-control header #22270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: production
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Cache Reserve is a large, persistent data store [implemented on top of R2](/r2/)

![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](~/assets/images/cache/content-being-served.png)

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](/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.
How long content in Cache Reserve will be considered “fresh” is determined by Edge Cache TTL setting or [Cache-Control headers at your origin](/cache/concepts/cache-control/), if [Edge Cache TTL](/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. If an asset is not requested within the retention period, it will be evicted from Cache Reserve. Accessing the asset will extend the retention period by one period. By default, the Cache Reserve retention period is 30 days.

Expand Down
7 changes: 4 additions & 3 deletions src/content/docs/cache/concepts/cache-control.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pcx_content_type: concept
head:
- tag: title
content: Origin Cache Control
description: Learn how the 'cache-control' header works with Cloudflare's Origin Cache Control feature, which ensures that Cloudflare respects caching directives from your origin server.

---

Expand All @@ -24,9 +25,9 @@ In the following sections, we will provide more details regarding:
* How Origin Cache Control behaves with `Cache-Control` directives.
* How other Cloudflare products interact with `Cache-Control` directives.

## `Cache-control` directives
## `Cache-control` header 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.
A `Cache-Control` header can include a number of directives. The `Cache-Control` header's directives dictate who can cache a resource along with how long those resources can be cached before they must be updated.

:::note[Note]

Expand Down Expand Up @@ -86,7 +87,7 @@ The `stale-if-error` directive is ignored if [Always Online](/cache/how-to/alway
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](/cache/advanced-configuration/vary-for-images/) is configured and when the vary header is [`vary: accept-encoding`](/speed/optimization/content/compression/).
* `vary` — Cloudflare does not consider vary values in caching decisions. Nevertheless, vary values are respected when [Vary for images](/cache/advanced-configuration/vary-for-images/) is configured and when the vary `cache-control` header is [`vary: accept-encoding`](/speed/optimization/content/compression/).
Copy link
Contributor

@angelampcosta angelampcosta May 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think vary is a cache-control header.

* `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
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/cache/concepts/cache-responses.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The resource was served from Cloudflare's cache but was expired. Cloudflare coul

## 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](/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](/cache/concepts/cache-control/#conditions) in the Origin Cache-Control behavior section for more details.
The origin web server instructed Cloudflare to bypass cache via a [`Cache-Control` header](/cache/concepts/cache-control/) 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](/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](/cache/concepts/cache-control/#conditions) in the Origin Cache-Control behavior section for more details.

## REVALIDATED

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/cache/concepts/customize-cache.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ For example, add a `static=true` query string for resources at your origin web s
* 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](/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.
Resources that match a Cache Everything Cache Rule are still not cached if the origin web server sends a [Cache-Control header](/cache/concepts/cache-control/) of `max-age=0`, `private`, `no-cache`, or an `Expires` header with an already expired date. Include the [Edge Cache TTL](/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.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { FeatureTable } from "~/components"
Cloudflare respects the origin web server’s cache headers in the following order unless an [Edge Cache TTL cache rule](/cache/how-to/cache-rules/settings/#edge-ttl) overrides the headers. Refer to the [Edge TTL](/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 [`Cache-Control` header](/cache/concepts/cache-control/) is set to `private`, `no-store`, `no-cache`, or `max-age=0`.
* The [Set-Cookie header](/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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { Example, Render } from "~/components"
* **Then**:
* **Cache eligibility**: Eligible for cache
* **Setting**: Edge TTL
* Use cache-control header if present, use default Cloudflare caching behavior if not
* Use [cache-control header](/cache/concepts/cache-control/) if present, use default Cloudflare caching behavior if not
* **Status code TTL**:
* **Scope**: *Range*
* **From**: *200*
Expand Down
4 changes: 2 additions & 2 deletions src/content/docs/cache/how-to/cache-rules/settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ If you use cache rules, image transformations, and zone versioning simultaneousl

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, bypass cache if not**: If a [cache-control header](/cache/concepts/cache-control/) 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](/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.

Expand All @@ -93,7 +93,7 @@ API configuration object name: `"edge_ttl"`.

| API values | Configuration |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `respect_origin` | Use cache-control header if present, use default [Cloudflare caching behavior](/cache/concepts/default-cache-behavior/) if not. |
| `respect_origin` | Use [cache-control header](/cache/concepts/cache-control/) if present, use default [Cloudflare caching behavior](/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. |
| | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ For more information on how to set up Edge Cache TTL, refer to [Cache rules](/ca

## 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 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](/cache/concepts/cache-control/) 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.
Expand All @@ -28,7 +28,7 @@ Unless specifically set in a cache rule, Cloudflare does not override or insert

* 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.
* Purging Cloudflare’s cache does not affect assets stored by a visitor’s browser.
:::

<FeatureTable id="cache.browser_cache_ttl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sidebar:

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](/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:
By default, Cloudflare honors the cache expiration set in your `Expires` and [`Cache-Control` headers](/cache/concepts/cache-control/). 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.
Expand All @@ -33,7 +33,7 @@ If you modify cached assets, the new asset is not displayed to repeat visitors b
2. Select **Caching**.
3. Under **Browser Cache TTL**, select the drop-down menu to select the desired cache expiration time.

The **Respect Existing Headers** option tells Cloudflare to honor the settings in the `Cache-Control` headers from your origin web server.
The **Respect Existing Headers** option tells Cloudflare to honor the settings in the [`Cache-Control` headers](/cache/concepts/cache-control/) from your origin web server.

:::note[Respect Existing Headers Availability]

Expand Down
4 changes: 2 additions & 2 deletions src/content/docs/rules/reference/page-rules-migration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ You configured a Page Rule turning on caching of every response with status code
- **Then**:
- **Cache eligibility**: Eligible for cache
- **Setting**: Edge TTL
- Use cache-control header if present, use default Cloudflare caching behavior if not
- Use [cache-control header](/cache/concepts/cache-control/) if present, use default Cloudflare caching behavior if not
- **Status code TTL**:
- **Scope**: _Range_
- **From**: _200_
Expand Down Expand Up @@ -803,7 +803,7 @@ You configured a Page Rule adjusting Edge Cache TTL for all subdomains of `examp
- **Then**:
- **Cache eligibility**: Eligible for cache
- **Setting**: Edge TTL
- Ignore cache-control header and use this TTL
- Ignore [cache-control header](/cache/concepts/cache-control/) and use this TTL
- **Input time-to-live (TTL)**: _1 day_

</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Assets stored in the cache through [Cache API](/workers/runtime-apis/cache/) ope

## Edge versus browser caching

The browser cache is controlled through the `Cache-Control` header sent in the response to the client (the `Response` instance return from the handler). Workers can customize browser cache behavior by setting this header on the response.
The browser cache is controlled through the [`Cache-Control` header](/cache/concepts/cache-control/) sent in the response to the client (the `Response` instance return from the handler). Workers can customize browser cache behavior by setting this header on the response.

Other means to control Cloudflare’s cache that are not mentioned in this documentation include: Page Rules and Cloudflare cache settings. Refer to the [How to customize Cloudflare’s cache](/cache/concepts/customize-cache/) if you wish to avoid writing JavaScript with still some granularity of control.

Expand Down