Render provides **edge caching** for static assets (documents, images, etc.) served by paid [web services](/content/docs/web-services/index.html). With edge caching enabled, you can speed up response times and reduce load on your web service:

Edge caching is powered by the same global CDN as Render [static sites](/content/docs/static-sites/index.html).

## Setup

**Edge caching is not available for [free web services](/content/docs/free/index.html).**

1. In the [Render Dashboard](https://dashboard.render.com/), open your web service's **Settings** page and scroll down to the **Edge Caching** section:

2. Under **Cacheable file types**, click the dropdown and select an option:

| Option | Description |
| --- | --- |
| **None** | Disables edge caching. All assets are served from your web service.<br>This is the default option. |
| **Common static files** | Unless overridden by a [`Cache-Control` header](/content/docs/web-service-caching#setting-cache-control-headers/index.html), Render caches assets with the following file types:<br>`7z``avi``avif``bin``bmp``bz2``class``css``csv``dmg``doc``docx``eot``ejs``eps``exe``flac``gif``gz``ico``iso``jar``jpeg``jpg``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`<br>Other file types are _never_ cached, regardless of `Cache-Control` headers. |
| **All files** | Unless overridden by a [`Cache-Control` header](/content/docs/web-service-caching#setting-cache-control-headers/index.html), _all_ of your service's eligible responses are cached, regardless of file type. **This might include dynamic content.**<br>If you use this option, make sure to [set `Cache-Control` headers](/content/docs/web-service-caching#setting-cache-control-headers/index.html) for dynamically generated content to prevent it from being cached. Otherwise, you might serve the wrong version of that content to clients. |

3. After you select an option, a confirmation dialog appears. Review and **Confirm** the notices, then click **Save changes**.

You're all set! Render begins caching your web service's [cache-eligible responses](/content/docs/web-service-caching#cache-eligibility/index.html).

## How edge caching works

Whenever a client sends an HTTP request to your cache-enabled web service, Render determines whether the request is eligible to serve from the edge cache. (For details, see [Cache eligibility](/content/docs/web-service-caching#cache-eligibility/index.html).)

If the request is cache-eligible, Render checks the edge cache for the corresponding resource.

- **If the requested resource is in the cache** (and the entry isn't stale), Render serves the cached version:

In this case, the request never reaches your web service. This speeds up the response and reduces load.

- **Otherwise,** Render fetches the resource from your web service and—if it's _also_ cache-eligible—caches it for future requests:

### Cache eligibility

When serving a request from your web service, Render uses the following logic to determine whether the response can be cached for future requests:

**Yep!**

**Nope, some other**

**HTTP method.**

**Yep!**

**Nope.**

**Yep!**

**Header is**

**not present.**

**Header is present, but**

**it disallows caching.**

**Yep!**

**Nope.**

Is the request method

either GET or HEAD?
Does the asset have a

_cacheable file type?*_*

Does the response include a Cache-Control header that allows caching?
Is the HTTP status code

_cacheable by default?*_*

❌

Response is **not**
cache-eligible.

✅

Response is

cache-eligible!

\* See details below.
To summarize, **all** of the following must be true for a response to be cache-eligible:

- The originating request **must** use the `GET` or `HEAD` HTTP method.
- The requested resource **must** have a [cacheable file type](/content/docs/web-service-caching#cacheable-file-types/index.html) based on your settings.
- The response **must either** include a `Cache-Control` header that allows caching **or** have a [default-cacheable status code](/content/docs/web-service-caching#default-cacheable-status-codes/index.html).
- Additionally, the response **must not** include a `Set-Cookie` header.

#### Cacheable file types

When you [enable edge caching](/content/docs/web-service-caching#setup/index.html) for your web service, you select one of the following options for **Cacheable file types**:

| Option | Description |
| --- | --- |
| **Common static files** | Unless overridden by a [`Cache-Control` header](/content/docs/web-service-caching#setting-cache-control-headers/index.html), Render caches assets with the following file types:<br>`7z``avi``avif``bin``bmp``bz2``class``css``csv``dmg``doc``docx``eot``ejs``eps``exe``flac``gif``gz``ico``iso``jar``jpeg``jpg``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`<br>Other file types are _never_ cached, regardless of `Cache-Control` headers. |
| **All files** | Unless overridden by a [`Cache-Control` header](/content/docs/web-service-caching#setting-cache-control-headers/index.html), _all_ of your service's eligible responses are cached, regardless of file type. **This might include dynamic content.**<br>If you use this option, make sure to [set `Cache-Control` headers](/content/docs/web-service-caching#setting-cache-control-headers/index.html) for dynamically generated content to prevent it from being cached. Otherwise, you might serve the wrong version of that content to clients. |

#### Default-cacheable status codes

If your web service returns a cache-eligible response _without_ a [`Cache-Control` header](/content/docs/web-service-caching#setting-cache-control-headers/index.html), Render caches the response if it has one of the following status codes (and applies the corresponding default TTL):

| Status code | Default TTL |
| --- | --- |
| 200, 206, 301 | 120 minutes |
| 302, 303 | 20 minutes |
| 404, 410 | 3 minutes |

### Invalidation and expiration

To help ensure that clients receive up-to-date content, Render invalidates edge cache entries in the following scenarios:

| Scenario | Description |
| --- | --- |
| **New deploys** | Each time you successfully deploy a new version of your web service, Render purges _all_ of the service's edge cache entries. This way, the cache doesn't serve stale content from the service's previous version.<br>Render waits until all of the previous version's instances have shut down before purging the cache (learn more about [zero-downtime deploys](/content/docs/deploys#zero-downtime-deploys/index.html)). Failed deploys do _not_ trigger a purge.<br>Purging the cache might briefly increase your web service's request volume, but only slightly. [See details](/content/docs/web-service-caching#load-protection-on-cache-purge/index.html). |
| **TTL expiration** | Each cache entry has a corresponding time-to-live (TTL). When an entry's TTL expires, the entry is considered stale. The next request for a stale entry is sent to your web service, which refreshes the entry. |
| **Manual purge** | You can trigger a cache purge for your web service from its **Settings** page in the [Render Dashboard](https://dashboard.render.com/):<br><br>As with a new deploy, this purges _all_ of your web service's associated edge cache entries.<br>Purging the cache might briefly increase your web service's request volume, but only slightly. [See details](/content/docs/web-service-caching#load-protection-on-cache-purge/index.html). |

#### Load protection on cache purge

Whenever you purge your web service's edge cache (either manually or by triggering a new deploy), Render's CDN automatically protects your web service from receiving a sudden influx of requests.

If multiple clients request the same uncached resource, Render's CDN forwards only _one_ of those requests along to your web service. The CDN caches your web service's response, then serves it to all waiting clients. This pattern is called **request collapsing**.

Your web service might experience a brief traffic increase after a cache purge, but thanks to request collapsing, the size of that increase is roughly equal to the number of _unique resources_ being requested. This is usually a small fraction of your service's total request volume.

## Setting `Cache-Control` headers

You can customize Render's edge caching behavior for a particular resource by including a [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control) (or `CDN-Cache-Control`) header in your web service's response:

httpCopy to clipboard

```http
Cache-Control: public, max-age=7200
```

**New to cache control headers?**

Learn more about supported [response directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#response_directives).

| Customization | Description |
| --- | --- |
| **Set a TTL (time-to-live)** | Do **both** of the following in your response's `Cache-Control` header:<br>- Include the `public` directive.<br>- Set the `max-age` or `s-maxage` directive to a value greater than `0`.<br>httpCopy to clipboard<br>```http<br>Cache-Control: public, max-age=3600<br>``` |
| **Disable caching** | Do **either** of the following in your response's `Cache-Control` header:<br>- Include the `no-store` directive to prevent storage in all caches.<br>- Include `private, max-age=0, no-transform` to prevent storage in the edge cache while allowing browser storage with revalidation.<br>httpCopy to clipboard<br>```http<br>Cache-Control: private, max-age=0, no-transform<br>``` |
| **Set revalidation behavior** | Include a combination of the `must-revalidate`, `stale-while-revalidate`, and `stale-if-error` directives.<br>httpCopy to clipboard<br>```http<br>Cache-Control: stale-while-revalidate=60, stale-if-error=3600, public, max-age=1200<br>``` |

### Precedence rules

Render applies the following precedence rules to cache control headers:

- The `CDN-Cache-Control` header takes precedence over the `Cache-Control` header if both are present.
- The `s-maxage` directive takes precedence over the `max-age` directive if both are present.

## Inspecting cache behavior

Each response from a cache-enabled web service includes a `CF-Cache-Status` header:

httpCopy to clipboard

```http
CF-Cache-Status: HIT
```

The value of this header indicates whether the response interacted with the edge cache and in what way. The most common values are:

| Value | Description |
| --- | --- |
| `HIT` | The response was served from the edge cache. |
| `MISS` | The response was not found in the edge cache. It was served from your web service and cached if eligible. |
| `DYNAMIC` | Some element of the incoming HTTP request was not [cache-eligible](/content/docs/web-service-caching#cache-eligibility/index.html), and the response was served from your web service.<br>Most commonly indicates one of the following:<br>- The request used an HTTP method other than `GET` or `HEAD`.<br>- The requested resource did not have a [cacheable file type](/content/docs/web-service-caching#cacheable-file-types/index.html) based on your settings. |
| `EXPIRED` | The response was found in the edge cache, but its TTL had expired. It was served from your web service and the edge cache was updated with the new response. |
| `BYPASS` | The response was served directly from your web service and was _not_ stored in the edge cache, usually for one of the following reasons:<br>- The response included a `Cache-Control` header that disabled caching.<br>- The response did _not_ include a `Cache-Control` header, and it returned a status code that is not [default-cacheable](/content/docs/web-service-caching#default-cacheable-status-codes/index.html).<br>- The response included a `Set-Cookie` header.
