Configuring Cloudflare's browser and edge node caching
Among the advantages of using Cloudflare as DNS provider for a domain is access to their global content delivery network (CDN), and the ability to cache website content at their edge nodes and to control browser caching. Caching is active by default when you use Cloudflare, but you can tweak it to better match your requirements.
Browser caching happens when a user visits a website and downloads an asset such as a stylesheet or an image. The browser will store the asset for a while so it can be used again, should the user return to the page or website later. Instead of retrieving the image again from the web server, the browser will just use the stored image. You can see this behavior in action if you open your browser's developer tools on the "Network" tab before visiting a website. If you use Chrome, you will see a list of assets retrieved from the web server, and if you look in the "Size" column, you will see how many bytes were downloaded. Refresh the page and the list will be populated again, but this time some of the rows will have
(memory cache) or
(disk cache) instead of the download size.
Browser caching has benefits for both the user and for those running the web server. The user saves time and bandwidth, and the web server has less work to do (so it can handle more visitors). From a developer perspective, however, it means that we need to be prepared to handle situations where an asset that is being updated has already been accessed and cached by website visitors.
Say that your websites' stylesheet is "style.css". If you change a css rule that affects something on a web page, you will most likely want everyone to see the change on their next visit. But someone who visited the page recently will have the old stylesheet cached, and they will see the old styling until their cache expires (or until they do a hard browser refresh). This can bite you hard if the browser cache lifetime is long - you will simply have to wait until that time has passed before you can be sure that everyone has the update.
Dealing with browser caching
There are two main ways of dealing with browser caching:
- Change asset names whenever they are updated
- Reduce cache lifetime, or request that the asset is never cached.
The first strategy is very effective, but it requires a build system that can assign new names to assets when they change. Typically some sort of content hash is added to the file name, e.g. "style.33869c3ff7.css" or similar. The build system ensures that the middle part of the file name - the hash - is changed if the css is updated. This completely solves the problem of stale assets, because updated assets will have different names from those stored in the browser cache.
Reducing the cache lifetime is a reasonable alternative if you cannot change the names of assets. You could decide, for example, that an hour is an acceptable time to wait between deploying an update and being sure that all website visitors have it. This will allow visitors to browse the website without having to download the same assets repeatedly in the same session, but they will need to download them again if they leave and come back later.
Browser cache lifetime is controlled by HTTP headers sent by the web server. There are many ways to accomplish this, but if you are using Cloudflare, it can do it for you. Cloudflare will look in the response headers coming from the web server, and if there are no
Expires headers, it will add them for you. If either header is found in the response, but the cache lifetime specified is less than that configured at Cloudflare, it can update the header to use the longer lifetime.
On the free Cloudflare plan, browser cache lifetime can be set to anything from 2 minutes to a full year. (You can also tell Cloudflare to do nothing, leaving whatever reply headers are sent by the web server unmodified).
So what lifetime should you choose? Cloudflare defaults to four hours, which is a reasonable compromise, but if you expect your visitors to come back to the website regularly, you should probably set a longer value.
CDN edge caching
While browser caching can speed up access to a website for individual users, edge caching can improve access speeds for larger groups. When a website visitor requests an asset, it is delivered via Cloudflare's CDN to an edge node close to the visitor. The edge node will store the asset for a while, and if another user accesses the website via the same node, it can deliver the asset immediately without having to pass the request back to the web server. As with browser caching, website access speed is improved and server load is reduced.
(If another website visitor accesses the website via a different edge node, that node may not have the asset in its cache, so in that case the request will have to passed back to the web server. To improve edge cache performance, Cloudflare has recently introduced "tiered caching", where a subset of CDN nodes are responsible for retrieving assets from the web server and distributing them to the other edge nodes when they are needed, which can improve cache performance when visitors come from many different geographic locations).
From a developer perspective, edge caching is much easier to deal with than browser caching because the cache can be manually flushed if necessary, removing selected assets (or all assets) from the cache. On the paid Cloudflare plans it is possible to specify a time-to-live value, e.g. one hour, after which the CDN will fetch a fresh copy from the web server. On the free plan, assets will generally remain cached for an extended period of time unless manually flushed.
If your website is statically generated (using eleventy, for example), it is possible to cache the website HTML in addition to the static assets, potentially caching the entire website in the CDN.
Caching website HTML requires use of Cloudflare's page rules. In the case where you want to cache an entire website, only a single page rule is required, but it is possible to use different caching policies for different parts of the website by creating multiple page rules. (The first three page rules per domain are included in the free Cloudflare plan. If you need more you can purchase additional page rules at $5 per five additional page rules).
HTML caching is also possible with a dynamic website, e.g. WordPress, but care must be taken to only cache the parts of the website that look the same to all users. This can be done using page rules, but in practice it would be much easier to use a plugin that supports Cloudflare. One option is Cloudflare's own Automatic Platform Optimization for WordPress
HTML caching works the same as edge caching of static assets, and has similar advantages and disadvantages. The main drawback is that, on the free plan, you will need to manually purge the cache using Cloudflare's control panel or their CLI tool when you make updates to the website.