Knowledge
How to enable Gzip and Brotli compression in Nginx
#Performance
Learn how to enable Gzip compression in Nginx (and add Brotli) to shrink text assets and speed up page loads, with real config and verification commands.
Published by Mark van Eijk on June 23, 2026 · 4 minute read
- Enable Gzip in Nginx
- Reload Nginx
- Verify it works
- Add Brotli for a better ratio
- Which should you choose
- Conclusion
Compression is one of the cheapest performance wins you can ship. Text assets like HTML, CSS, JavaScript, and JSON compress extremely well, often by 70-80%, so enabling it cuts transfer size and improves load time for every visitor. The good news: to enable Gzip compression in Nginx you only need a handful of directives. This guide covers Nginx Gzip, then adds Brotli for an even better ratio.
Enable Gzip in Nginx
Gzip is built into Nginx, so enabling it is just configuration. Add this to the http {} block in /etc/nginx/nginx.conf (or a file included from it):
http {
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_vary on;
gzip_proxied any;
gzip_types
text/plain
text/css
text/xml
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
}
What each directive does:
gzip on— turns compression on. By default Nginx only compressestext/html, which is whygzip_typesmatters.gzip_types— the MIME types to compress. List your text-based assets here. There's no point compressing already-compressed formats like JPEG, PNG, or WOFF2, so leave those out.gzip_comp_level— compression effort from 1 to 9. Higher means smaller files but more CPU per request. Levels 4-6 are the sweet spot; past that you burn CPU for marginal size gains. Start at 5.gzip_min_length 256— skip tiny responses. Compressing a 50-byte payload can make it larger and wastes CPU, so only compress responses of at least 256 bytes.gzip_vary on— addsVary: Accept-Encodingso caches and CDNs store compressed and uncompressed variants separately.gzip_proxied any— compress responses even when the request comes through a proxy. Useful behind a load balancer or CDN.
Reload Nginx
Always test the config before reloading so a typo doesn't take the server down:
nginx -t && systemctl reload nginx
nginx -t validates the syntax; the reload only runs if the test passes. A reload is graceful, so existing connections aren't dropped.
Verify it works
Don't assume it's working, check the response headers. Request a text asset and ask for Gzip:
curl -H 'Accept-Encoding: gzip' -I https://example.com
Look for this in the output:
content-encoding: gzip
vary: Accept-Encoding
If Content-Encoding: gzip is present, compression is active. If it's missing, the most common causes are the response type not being in gzip_types, the body being under gzip_min_length, or a proxy in front stripping the Accept-Encoding header. Note that browsers send Accept-Encoding automatically; the -H flag just forces it for the test.
Add Brotli for a better ratio
Brotli typically compresses 15-25% smaller than Gzip on text, and every modern browser supports it. The catch: Brotli is not bundled with Nginx by default. You need the ngx_brotli module, either compiled in or loaded as a dynamic module.
On Debian/Ubuntu the dynamic modules are often available as a package:
apt install libnginx-mod-brotli
Then load the modules at the very 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;
Now configure Brotli inside http {}, alongside Gzip. Keeping both means clients that don't support Brotli still fall back to Gzip:
http {
brotli on;
brotli_comp_level 5;
brotli_types
text/plain
text/css
application/json
application/javascript
image/svg+xml;
# static precompression
brotli_static on;
gzip_static on;
}
brotli_static on and gzip_static on enable static precompression: if a style.css.br or style.css.gz file sits next to style.css, Nginx serves the precompressed version directly instead of compressing on the fly. This is ideal for build artifacts, you compress once at deploy time at maximum level and pay zero CPU per request. Generate the files in your build step and ship them alongside the originals.
Test and reload exactly as before:
nginx -t && systemctl reload nginx
To verify Brotli, ask for it explicitly and check for content-encoding: br:
curl -H 'Accept-Encoding: br' -I https://example.com
Which should you choose
You don't have to choose, run both. Configure Brotli and Gzip together and let the browser negotiate: capable clients get Brotli, everything else falls back to Gzip. For a deeper comparison of ratios and CPU cost, see Brotli vs Gzip.
Conclusion
Enabling Gzip in Nginx is a few directives and a reload, and it pays off on every text response you serve. Add gzip on with a sensible gzip_types list and gzip_comp_level 5, confirm it with curl, then layer Brotli on top via ngx_brotli for a better ratio with Gzip as the fallback. For build assets, precompress with brotli_static/gzip_static to get maximum compression at no runtime cost.
Compression is one piece of the puzzle. To go further, see how it fits into optimizing website performance and how serving precompressed assets helps your time to first byte.
Subscribe to our newsletter
Do you want to receive regular updates with fresh and exclusive content to learn more about web development, hosting, security and performance? Subscribe now!
Related articles
How to optimize server performance
Learn how to enable Gzip compression in Nginx (and add Brotli) to shrink text assets and speed up page loads, with real config and verification commands.
How to measure TTFB (Time To First Byte)
Learn how to enable Gzip compression in Nginx (and add Brotli) to shrink text assets and speed up page loads, with real config and verification commands.