01 Feb 2021  guides

Cache-Busting in BunnyCDN using Jekyll Timestamps

There’s an easy way of combining Jekyll functionality with BunnyCDN’s features to ensure your visitors always get the most recent version of your assets (namely your CSS stylesheet), thus preventing any stale cache in the browser from overriding newly deployed assets.

Reference BunnyCDN

The first thing to do after setting up your BunnyCDN Pull Zone is to configure Jekyll to serve CSS, JS, and other assets from the CDN instead of your origin server.

An easy way to work with CDN URLs in Jekyll is by using variables. Here’s an example from my _config.yml file that makes the variable containing the Pull Zone URL accessible across my entire site:

assets: "https://assets.paramdeo.com"

Serve CSS from BunnyCDN

In my head.html (or wherever you have your CSS relationship declared), I’ve change the location of the stylesheet to match the following:

<link href="{{ site.assets }}/css/style.css" rel="stylesheet">

Now when I build my site, the CSS will be served from the CDN directly.

Vary Cache from BunnyCDN at Build Time

BunnyCDN has a feature in their Pull Zone options that allows for varying the cache via URL Query String. You can find this option in your BunnyCDN account by navigating to Pull Zones > foobar > Caching > General.

Scrolling to the bottom under Vary Cache displays the following options:

Once that’s configured, if for example I request https://assets.paramdeo.com/css/style.css?text=123456 I would be served up a fresh CSS file from BunnyCDN, which effectively invalidates the older version that exists in my (and my user’s) local browser cache. The only thing left to do then is automate this cache-busting process.

Generate Query String at Build Time

Timestamps in Jekyll are generally used when referring to the time a page/post was published, but Jekyll also has a variable called {{ site.time }} which returns the current time (i.e. the time that Jekyll processed that variable when building/serving). If you glance at my site’s footer, this is what I use to effectively display the build time of my site.

{{ site.time }} accepts the same filtering arguments for formatting  as any other Liquid variable in Jekyll. And because the site’s timestamp is generated when a build is run, it will always be unique.

The goal is to therefore choose a timestamp format that can be validly passed to a query string, i.e. no spaces or special characters. For this purpose, Jekyll handily provides the %s placeholder that returns an integer representing the number of seconds since 1970-01-01 00:00:00 UTC (which is also known as UNIX Time).

Going back to my earlier CSS markup in head.html, I can now insert this variable:

<link href="{{ site.assets }}/css/style.css?timestamp={{ site.time | date: '%s' }}" rel="stylesheet">

An example of the above output after I’ve built my site looks like https://assets.paramdeo.com/css/style.css?timestamp=1612197275. Such a URL will be different each time the site is built, and therefore will cause the user to fetch a fresh version of the site’s CSS.

In this way, I can lengthen the time that CSS and other assets are cached in BunnyCDN, while keeping the HTML cache value lower. This allows a visitor to pull fresher HTML (which will reflect changes to my content) and also invalidate the browser’s CSS cache if the HTML tells it to do so.

While this method caters to Jekyll and BunnyCDN, varying the cache via a query string is a feature that’s built into most other Content Delivery Networks, and most Static Site Generators support generating a timestamp string at build time.

Webmentions & Comments

Copyright © Paramdeo Singh. Built with Jekyll and ❤ in Guyana. All Rights Reserved.

Last Site Build on Tue, 13 Apr 2021 16:55:04 -0400

1MB Club Badge