Traefik’s Compress middleware can significantly reduce bandwidth usage and improve load times for your users by automatically compressing responses using gzip and Brotli.
Here’s how it works in a real-world scenario. Imagine you have a web application served by Traefik, and you want to ensure static assets like CSS and JavaScript files are compressed.
http:
routers:
my-app:
rule: "Host(`myapp.example.com`)"
service: "my-app-service"
middlewares:
- "compress"
services:
my-app-service:
loadBalancer:
servers:
- url: "http://192.168.1.100:8080"
middlewares:
compress:
compress:
# Enable gzip compression
gzip: true
# Enable Brotli compression (if supported by the client)
brotli: true
# Optionally, set a minimum threshold for compression.
# Files smaller than 1KB won't be compressed.
minLength: 1024
When a client (like a web browser) makes a request, it sends an Accept-Encoding header indicating which compression algorithms it supports. For example:
Accept-Encoding: gzip, deflate, br
Traefik inspects this header. If gzip is present and the gzip option is enabled in the middleware, Traefik will compress the response using gzip. If br (Brotli) is present and brotli is enabled, Traefik will attempt to use Brotli. Brotli generally offers better compression ratios than gzip, so it’s often preferred.
The minLength option is crucial. Compressing very small files can sometimes add more overhead than it saves due to the compression and decompression process. Setting a reasonable minLength ensures that only files large enough to benefit from compression are actually compressed.
Let’s see this in action with actual HTTP requests and responses.
Client Request:
GET /static/styles.css HTTP/1.1
Host: myapp.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept: text/css,*/*;q=0.1
Accept-Encoding: gzip, deflate, br
Traefik’s Response (if Brotli is enabled and supported):
HTTP/1.1 200 OK
Content-Encoding: br
Content-Type: text/css
Content-Length: 1500 # Original size might be 3000 bytes
Vary: Accept-Encoding
Date: Tue, 15 Nov 2023 10:00:00 GMT
Server: Traefik
[Brotli-compressed CSS data...]
Traefik’s Response (if only Gzip is supported/enabled):
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Type: text/css
Content-Length: 1800 # Original size might be 3000 bytes
Vary: Accept-Encoding
Date: Tue, 15 Nov 2023 10:00:00 GMT
Server: Traefik
[Gzip-compressed CSS data...]
Notice the Content-Encoding header. This tells the client how the content is encoded, and the Vary: Accept-Encoding header is important for caching. It signals to intermediate caches (like CDNs or browser caches) that the response varies based on the Accept-Encoding header, preventing them from serving a gzipped version to a client that only accepts plain text, or vice-versa.
The core problem this middleware solves is the inefficient transfer of data over the network, especially for text-based assets which are highly compressible. By intelligently compressing responses, you reduce the amount of data that needs to be sent between your server and the client, leading to faster page load times and a better user experience, particularly for users on slower networks or with limited data plans.
Internally, Traefik’s Compress middleware hooks into the response pipeline. Before the response is sent to the client, it checks the Accept-Encoding header. Based on the client’s capabilities and the middleware’s configuration (gzip, brotli), it selects the most appropriate compression algorithm. It then applies that algorithm to the response body and adds the corresponding Content-Encoding header. The minLength check is performed before compression to avoid unnecessary processing.
A less commonly known but powerful aspect of this middleware is its ability to handle multiple compression types simultaneously. If a client advertises support for both gzip and br, and both are enabled in Traefik, Traefik will prioritize Brotli because it typically achieves better compression ratios. This intelligent selection ensures optimal performance without manual configuration for each client type. If brotli is not enabled or not supported by the client, it falls back to gzip if that’s enabled and supported.
The next step after optimizing bandwidth is often handling caching effectively, which is where headers like Cache-Control and the Vary header become even more critical.