Optimizing images for the web with WebP

I recently converted all images on this site from PNG and JPEG to WebP. The results were better than I expected, so here are some quick notes. Why WebP WebP produces smaller files than PNG and JPEG at comparable visual quality. Browser support is effectively universal now — every modern browser has supported it for years. There is no reason to keep serving older formats for new content. Converting with cwebp The cwebp command-line tool (part of the libwebp package) handles conversion: ...

February 27, 2026 · 2 min · Martin Lindqvist

Speed testing your server from multiple locations

Running a speed test from your own machine tells you about one path. To get a broader picture of your server’s connectivity, you need to test from multiple locations. Here are the approaches I use. ping.pe ping.pe is one of the simplest tools for this. Enter your server’s IP or hostname and it runs ping, MTR, and port checks from dozens of locations simultaneously. The results show up in a live grid. ...

January 26, 2026 · 4 min · Martin Lindqvist

Setting up a self-hosted speed test with LibreSpeed

I wanted an independent way to test the connection speed to my server without relying on third-party services. LibreSpeed is an open-source speed test that you can host yourself. There is also a Go backend called speedtest-go that is self-contained and easy to deploy. This post covers setting up speedtest-go with a systemd service and an Nginx reverse proxy. Why self-host a speed test Public speed test services measure the connection between you and their servers, which is useful but does not tell you much about the connection to your specific server. A self-hosted instance measures exactly what you care about: the bandwidth and latency between a client and your VPS. ...

January 11, 2026 · 5 min · Martin Lindqvist

Caching strategies for static sites

Serving a static site is fast by default, but proper caching headers make a noticeable difference for repeat visitors. These are the headers I configure and why. Cache-Control This is the primary header that controls caching behavior. For static assets like CSS, JS, images, and fonts: location ~* \.(css|js|png|jpg|jpeg|webp|svg|woff|woff2|ico)$ { add_header Cache-Control "public, max-age=2592000, immutable"; } max-age=2592000 is 30 days. The immutable directive tells the browser not to revalidate the resource even on a normal reload. This works well when your build tool hashes filenames — if the content changes, the filename changes, so the old cached version is never requested again. ...

December 14, 2025 · 2 min · Martin Lindqvist