Gzip has been compressing web content since 1992. It’s good. It’s everywhere. And it’s showing its age. Brotli is its modern replacement — developed by Google, standardised in 2016 (RFC 7932), and now supported by every browser that matters. On typical web content, Brotli achieves 15–26% better compression than gzip at comparable speeds. Smaller files mean faster page loads, lower bandwidth costs, and better Core Web Vitals scores.
The myguard APT repository ships a native Brotli dynamic module for both NGINX and Angie — install it with one apt command, load it with one config line, and your server starts serving Brotli to every browser that supports it.
Brotli vs Gzip: The Actual Numbers
Brotli uses a combination of LZ77, Huffman coding, and a 2nd-order context modeling that gzip doesn’t have. The practical result:
| Content type | Gzip (level 6) | Brotli (level 6) | Brotli advantage |
|---|---|---|---|
| HTML | 68% reduction | 78% reduction | +15% |
| CSS | 72% reduction | 84% reduction | +21% |
| JavaScript | 67% reduction | 80% reduction | +19% |
| JSON API response | 71% reduction | 83% reduction | +17% |
| SVG | 74% reduction | 86% reduction | +19% |
Brotli level 11 (maximum) achieves 20–26% better compression than gzip, but is extremely slow to encode — suitable only for pre-compressed static assets, not on-the-fly. Level 4–6 is the sweet spot for on-the-fly dynamic compression: better than gzip, fast enough for real-time use.
Step 1 — Install the Brotli Module
# Add the myguard repository if not already done
wget https://deb.myguard.nl/pool/myguard.deb
dpkg -i myguard.deb
apt-get update
# Install NGINX with the Brotli module
apt-get install nginx libnginx-mod-http-brotli
# Or for Angie:
apt-get install angie angie-module-http-brotli
New to the myguard repository? Follow the two-minute setup guide.
Step 2 — Load the Module
The myguard package installs a load snippet automatically. Verify it’s in place:
ls /etc/nginx/modules-enabled/ | grep brotli
# Should show: 50-mod-http-brotli-filter.conf and 50-mod-http-brotli-static.conf
If not present, add to the top of nginx.conf (before the http block):
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
Step 3 — Configure Brotli
Add this inside your http block in nginx.conf:
http {
# Brotli dynamic compression (on-the-fly)
brotli on;
brotli_comp_level 6; # 0-11, sweet spot is 4-6
brotli_min_length 256; # Don't compress tiny responses
brotli_types
text/plain
text/css
text/javascript
text/xml
text/x-component
application/javascript
application/json
application/xml
application/rss+xml
application/atom+xml
application/vnd.ms-fontobject
image/svg+xml
font/truetype
font/opentype;
# Brotli static files (serve pre-compressed .br files)
brotli_static on;
# Keep gzip as fallback for browsers that don't support Brotli
gzip on;
gzip_comp_level 6;
gzip_min_length 256;
gzip_vary on;
gzip_types
text/plain text/css text/javascript application/javascript
application/json application/xml image/svg+xml font/opentype;
}
Step 4 — Test and Reload
nginx -t && systemctl reload nginx
Verify Brotli is working:
# curl with Brotli accept header
curl -H 'Accept-Encoding: br,gzip' -I https://example.com
# Look for: Content-Encoding: br
# Check Chrome DevTools: Network tab > select a request > Response Headers > Content-Encoding: br
Pre-Compressed Static Assets (Best Performance)
For static files that don’t change (CSS, JS, fonts), pre-compress them at build time with level 11 and let NGINX serve the .br files directly. This gives maximum compression with zero runtime CPU cost:
# Pre-compress all JS and CSS files in your web root
find /var/www/html -name '*.js' -o -name '*.css' | while read f; do
brotli -Z -f "$f" -o "${f}.br" # -Z = level 11
gzip -9 -k -f "$f" # -k = keep original, for fallback
done
With brotli_static on in your NGINX config, when a browser requests app.js with Accept-Encoding: br, NGINX automatically serves app.js.br without doing any runtime compression. Zero CPU, maximum compression.
# Install the brotli CLI tool
apt-get install brotli
Brotli for WordPress
WordPress sites benefit significantly from Brotli because WordPress generates a lot of HTML, CSS, and JavaScript. The main caveat: PHP responses are compressed dynamically, so set a sane compression level (4–6) to avoid adding more than ~1ms of CPU time per request.
Typical page size reduction for a WordPress homepage:
- Uncompressed HTML: ~180KB
- Gzip level 6: ~28KB
- Brotli level 6: ~23KB
- Brotli level 11 (pre-compressed): ~19KB
The 5KB difference between gzip and Brotli level 6 saves ~40ms on a typical 4G connection. Across thousands of page views, that’s meaningful for Core Web Vitals.
Brotli + zstd: Running Both
The myguard repository also ships a zstd NGINX module. zstd excels at server-side API compression (faster decode, great for JSON) while Brotli excels at browser-facing content (better compression ratio). Run both:
apt-get install libnginx-mod-http-brotli libnginx-mod-http-zstd
# In http block:
brotli on; # For browsers (HTML, CSS, JS)
brotli_types text/html text/css application/javascript image/svg+xml;
zstd on; # For API clients that support it
zstd_types application/json application/x-ndjson;
zstd_comp_level 3;
Frequently Asked Questions
Related Posts
- zstd NGINX Module: What It Does and 22 Bug Fixes — the other modern compression option, great for API workloads
- NGINX Dynamic Modules Overview — Brotli is one of 50+ available modules
- NGINX Performance and Security Expert Guide — full performance tuning guide including compression strategy
- NGINX vs Apache Benchmark 2026 — performance comparison including compression overhead
- How to Add the myguard APT Repository — where the Brotli module comes from