Caching and compression

23–

Introduction

My website, served by nginx on a VPS (Virtual Private Server) by Virtua.cloud in Lille (France) was already rather fast, but further improvement was possible. So I tried two things: better caching control, and gzip data compression.

Caching

What it is not

This is not about caching by web server nginx (which is mostly what you find when you google), but about caching by the browser: it remembers what has already been seen before, so it can reuse it when asked for it again, without having to fetch it from the web server over the internet.

Server-side caching wouldn’t make sense in my situation (would it ever?), because almost all of my content is in static HTML files, which the FS (filesystem: btrfs, but it could have been ext4) of the Linux OS (operating system) will already keep in its cache. Filesystem caching is probably just as efficient as nginx’s. So adding the latter would only introduce an extra layer of complexity that doesn’t improve anything.

My website has about 240 MB in HTML files, photos and sound files. Total server RAM size is 1 GB, of which spamassassin uses quite some. top says about 530 MB of RAM is used for caching. That means probably all of the website, which is on an already fast SSD (Solid State Drive), not HDD (Hard Disk Drive), can be permanently held in the fast RAM storage cache.

What it is

It is possible to configure web servers like Apache and nginx, in my case nginx, to send headers to the browser to tell it how to do its caching. I found info here.

Without any instructions, browsers also cache content, but they have to check back with the server every time to see if the cached version is still current. The settings no-cache and must-revalidate also have that effect, but in slightly different ways, as described on the Irish page I linked to a few seconds ago.

I decided to use the setting cache, with the consequence that if any resource with one the mentioned file name extensions (like css for a stylesheet, or woff for a compressed font) ever changes, the new version won’t be seen for at most 30 days.

But I prefer that, because these files are unlikely to change by now, and this cache setting removes the need to check back, which would have a performance penalty due to latency. Latency may add tens of milliseconds, or even hundreds, for each resource the check is done for. Clearly this can be significant.

location ~* ^.+\.(ico|css|js|gif|jpe?g|png|woff|woff2|eot|svg|ttf|webp)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control "public, cache";
}

Compression

Now does

Some years back, I don’t know exactly when, I just added gzip on at the server level of the nginx configuration. But that didn’t seem to work. Now more recently, on 20 October 2025, I found setting like these:

location ~* ^.+\.(htm|html|css|txt|c|js|xml)$ {
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/js text/xml
	application/json application/javascript application/x-javascript
	application/xml+rss application/atom+xml image/svg+xml;
}

And they worked, as can be verified using curl (see also wget), as follows:

curl https://rudhar.com/lingtics/intrlnga/introIED/intrenia.htm --silent \
	--write-out "%{size_download}\n" --output /dev/null

Result: 212195 bytes.

curl https://rudhar.com/lingtics/intrlnga/introIED/intrenia.htm --silent \
	-H "Accept-Encoding: gzip" \
	--write-out "%{size_download}\n" --output /dev/null

Result: 62757 bytes. Nice. Most files on my site are much smaller, but do also benefit from on the fly compression between server and browser.

SSI, Server Side Includes.

I thought I had it made, but on 21 October I noticed an unexpected complication: my gold pages showed no calculation data and no language links. Cause: somehow gzip compres­sion cannot work together with SSI – or rather, SSI can’t handle the compression.

This also affects some other directories:

../lingtics/irreverb
../lingtics/nomarvor
../lingtics/intrlnga/homophon/suggesti
../fonetics/iberx
../fonetics/nomesz
../etymolog/aoionon

Solution: from the list of file name extensions for which to do compression, htm|html|css|txt|c|js|xml, I removed stm (and inc, although that one wasn’t in the list in the first place). Bingo!

Brotli

I didn’t try brotli yet, which is a newer and better compression scheme developed by Google. I probably need to install an extra nginx component for that. Later, perhaps.

Speed tests

wget

Some speed insights can be obtained in a Linux command line, using wget (I take my recent article about the Google Search Console as an example):

time wget -p https://rudhar.com/sfreview/gseacnsl/en.htm

With an extra header the effect of compression can be observed:

time wget --header="Accept-Encoding: gzip" \
	https://rudhar.com/sfreview/gseacnsl/en.htm

Option -p not only downloads the file itself, but also any referenced CSS, Javascript etc. in other files. All results are stored in a directory tree starting from the current directory:

time wget -p https://rudhar.com/sfreview/gseacnsl/en.htm

Strangely, this doesn’t download the fonts hosted on my web server. But they are fetched when directly wget-ing the CSS:

time wget -p https://rudhar.com/css/seriose.css

The combination of compression and the -p option should work in my view, but doesn’t. The wget version I used is 1.21.3, built on linux-gnu.

web.dev

PageSpeed Insights is an interesting site for performance tests. It uses Google’s Lighthouse tool.

Some strange points: