This page describes Cloudflare's default caching behavior. Not all default behaviors are strictly RFC-compliant. Setting Origin Cache Control via page rules uses a newer set of caching rules that seeks to adhere more closely to RFCs, primarily with respect to revalidation--for example, our default behavior with max-age=0 is to not cache at all, whereas setting Origin Cache Control caches but always revalidates.
There are a few ways to alter the default behavior. The first is through Page Rules - a feature Cloudflare offers to fine tune how we interact with your site. There are two specific rules that take precedence:
- If a Page Rule is set to "Bypass Cache", then the resources that match that page rule will not be cached. Note that we will still act as a proxy, and our other performance features will still be active - content just won't be served from our cache and fetched from the origin directly.
- If a Page Rule is set to "Cache Everything", then resources that match the page rule will be cached. Note that this is the only way to tell us to cache resources beyond what we consider static, including HTML.
- If no Page Rule is set, then we will use the implicit Standard caching mode, and look at the extension of the resource to only cache static resources.
The second way to alter what Cloudflare will cache is through caching headers sent from the origin. Cloudflare will respect these settings, but you can also override them by specifying an Edge Cache TTL. Here are the caching headers we consider:
- If the Cache-Control header is set to "private", "no-store", "no-cache", or "max-age=0", or if there is a cookie in the response, then Cloudflare will not cache the resource.
- Otherwise, if the Cache-Control header is set to "public" and the "max-age" is greater than 0, or if the Expires headers are set any time in the future, we will cache the resource.
Note: As per RFC rules, "Cache-Control: max-age" trumps "Expires" headers. If we see both and they do not agree, max-age wins.
The third way to control Cloudflare caching behavior and browser caching behavior all in one go is by using the s-maxage Cache-Control header.
Normally we respect the max-age directive:
- Cache-Control: max-age=1000
But if a customer would like to specify a cache timeout in the CDN which is different from the browser we can also use s-maxage:
- Cache-Control: s-maxage=200, max-age=60
This will tell Cloudflare to cache the object for 200 seconds and the browser to cache the object for 60 seconds. Basically, s-maxage is intended to be followed ONLY by reverse proxies (so the browser should ignore it) whilst on the other hand, we (Cloudflare) give priority to s-maxage if present. Note that we will respect whichever value is higher: the browser cache setting in Cloudflare or the max-age header.
To sum up, here are the main areas to consider:
- Check your origin's caching headers to make sure there are no overriding headers for cacheable resources (Cache-Control and Expires).
- Cloudflare will cache static content by default. We will default to the following TTL depending on the return code:
200 301 120m; 302 303 20m; 403 5m; 404 5m; any 0s;
- To cache more, create a Page Rule set to cache everything on the desired URL (if your webserver returns a 404 when requesting this URL, we will still cache this result for 5min only, though). To avoid caching on a URL, create a rule to bypass the cache.
Our enterprise plan offers further customized caching beyond what is described here.