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.
- If a Page Rule is set to "Cache Everything", then resources that match the page rule will be cached. Note that this is the way to tell us to cache resources beyond what we consider static, including HTML.
- If no Page Rule is set, then we will look at the extension of the resource.
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.
Pro Tip: Sending cache directives from your origin for resources with extensions we don't cache by default will make absolutely no difference. To specify the caching duration at your origin for the extensions we don't cache by default, you'd have to create a Page Rule to "Cache Everything".
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 1m; 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 5mn 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.