Page caching with Batcache and Cloudflare
In this lesson you will learn how to install and configure the Batcache plugin
for WordPress. You'll hack through the advanced-cache.php file to make edge
caching possible with Cloudflare, and you'll also configure cache status
logging, to make sure you can accurately measure cache hit rates and response
times.
Note this lesson covers the Batcache page caching plugin for WordPress. If you're looking for an alternative, check out the Surge page caching lesson.
Batcache
Batcache is a full-page caching plugin for WordPress, originally developed for the WordPress.com network. It uses a persistent object cache to store the cache data. This is usually paired with a Memcached backend, but works just fine with Redis and other backends as well.
Despite its simplicity (only about 700 lines of code), and given the nature of many persistent object cache implementations, Batcache is suitable for decoupled and multi-server environments, where your cache services run separately from your web server. This gives it a strong advantage over local file-based solutions, such as WP Super Cache or Surge.
Installation
Batcache is not one of those plugins you can easily install and activate with a
couple of WP-CLI commands or by clicking around in your WordPress dashboard. You
will need to download the drop-in, symlink it manually, and enable it using your
wp-config.php file.
Despite being available on WordPress.org, the most up-to-date version still lives on GitHub. Luckily, GitHub is one of the few supported sources for WP-CLI plugin downloads:
cd /sites/uncached.org/public_html
wp plugin install https://github.com/Automattic/batcache/archive/refs/heads/master.zip
You can even "activate" the plugin:
wp plugin activate batcache
However what that activates is the helper plugin called the Batcache Manager, which provides a couple of functions developers can use to invalidate cache for posts and URLs. It also hooks these functions to invalidate caches when a new post is published or an existing one is updated.
To activate the caching plugin itself, you must symlink the page caching
drop-in to the wp-content directory:
cd /sites/uncached.org/public_html/wp-content
ln -s plugins/batcache/advanced-cache.php advanced-cache.php
As well as enable it in your wp-config.php file:
define( 'WP_CACHE', true );
After activation, Batcache appends cache information to every HTML response for anonymous visitors, for example:
<!--
generated 1 seconds ago
generated in 0.023 seconds
served from batcache in 0.000 seconds
expires in 299 seconds
-->
Batcache is typically configured by editing the settings inside the
advanced-cache.php file. However, it also supports predefining the $batcache
global array. A clean approach is to create a separate batcache-config.php
file if your changes are minimal.
<?php
global $batcache;
$batcache = [
'ttl' => 600,
'times' => 1,
];
Then load it early on from wp-config.php:
define( 'WP_CACHE', true );
require_once __DIR__ . '/batcache-config.php';
You can find all the available settings in the batcache class in the source
code.
For more advanced customizations, you will often need to resort to editing the
drop-in file directly.
Cloudflare integration
These steps are entirely optional, but as you'll see in the upcoming benchmarks, they make a huge difference, especially if your audience is scattered across different regions.
Batcache itself doesn't have great filters or events we can use to integrate with Cloudflare. It is still possible if you're willing to get your hands a little dirty, and update the drop-in file directly. There are a few things we need:
- Ensure a correct
Cache-Controlheader is being sent by Batcache. - Make sure Nginx serves the correct
Cache-Controlheader for static assets. - Change our Cloudflare zone settings to respect the
Cache-Controlheaders.
Batcache
Batcache already sends a Cache-Control header, which is derived from the TTL
setting and the expiration time of the cached request. This is usually okay for
a single-tier cache, but we typically don't want Cloudflare to cache our
dynamic requests for 300 seconds or longer, unless we have a simple way to
invalidate that cache.
This article is for premium members only. One-time payment of $96 unlocks lifetime access to all existing and future content on wpshell.com, and many other perks.