On Invalidation of Aggressively Cached Static Sites
I have always wanted to make this website load fast everywhere in the world, despite the server being in Montréal, Canada, without investing heavily. It shouldn’t be hard: after all, it is just a bunch of static files, generated with Jekyll.
Cloudflare brings a free CDN. You can set a page rule to aggressively cache your website on their CDN edge nodes, allowing your site to load as if it is hosted locally, even if you are half a world away.
There is just a little problem: how do you efficiently purge the cache when you update your site? It is quite easy to purge the entire cache on Cloudflare, but that is rather inefficient: most of your assets probably did not change, and now they will all have to be fetched again.
Today I decided to tackle this problem by creating purge-static
, a tool
designed to purge your CDN cache. It can purge your Cloudflare cache for you.
You can get started by running pip install purge-static
.
purge-static
works by keeping track of the hashes of every file you have on
your static site. When you run purge-static
, it finds new files and files
whose hash changed since the last time you run purge-static
, generates the
URLs, and either prints the list of URLs to be purged, or invokes your CDN’s
API to purge the URLs directly. Currently, only Cloudflare is supported,
but it should be relatively easy to add support for other CDNs.
With this tool, I am able to set Cloudflare to cache everything aggressively on the edge for a month:
The results are fairly promising. As you can see on this report, loading this website from Sydney, Australia — half a world away from Canada — takes less than half a second, and yet, as I push out a new blog post, it shows up almost immediately.
It is fairly easy to use. This is the (slightly redacted) command I am running to purge this website:
purge-static --cloudflare \
-c /etc/cfpurge.json \
https://quantum2.xyz \
-z 0123456789abcdeffedcba9876543210 \
-d /var/www/quantum \
-s /var/www/quantum-hashes.db \
-i '.*\.gz$|.*-[0-9a-f]{64}\.'
Essentially, this tells purge-static
to hit Cloudflare, with credentials in
the JSON file /etc/cfpurge.json
, purging quantum2.xyz
whose zone ID is
0123456789abcdeffedcba9876543210
. It also says that the URL
https://quantum2.xyz
maps to /var/www/quantum
, and we are storing the
hashes in a file at /var/www/quantum-hashes.db
.
Finally, it tells purge-static
to ignore a bunch of stuff. First, all .gz
files are ignored, since those are only needed for nginx
’s gzip_static
module, and are not sent to the user directly. Also, since I am using
jekyll-assets
, which adds hashes to asset URLs, there is no need to ever
purge those, so they are filtered out to save some effort.
I hope you find purge-static
useful! If you like it, be sure to star it on
GitHub!