Compression shrinks text responses (HTML, CSS, JS, JSON, SVG) by 70–90%. Put this at the http { } level so it applies everywhere.
gzip on;
gzip_vary on; # add "Vary: Accept-Encoding" so caches store both versions
gzip_comp_level 5; # 1–9; 5 is a good size/CPU trade-off
gzip_min_length 256; # don't bother compressing tiny responses
gzip_proxied any; # also compress responses to proxied requests
gzip_types
text/plain
text/css
text/xml
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml
font/ttf
font/otf;
Key points:
- HTML (
text/html) is always compressed when gzip is on — you don’t (and can’t) list it ingzip_types. gzip_vary on;is important behind a CDN/proxy so it caches the gzipped and plain versions separately.- Don’t compress already-compressed formats (JPEG, PNG, WebP, MP4, woff2) — they won’t shrink and you’d waste CPU. The list above deliberately omits them.
woff2is already compressed, so leave it out. gzip_comp_levelabove ~6 costs noticeably more CPU for little extra savings.
Brotli compresses ~15–20% smaller than gzip but needs the separate ngx_brotli module (not in stock Nginx; included in many distro builds and the official Docker image). If you have it:
brotli on;
brotli_comp_level 5;
brotli_types text/plain text/css application/json application/javascript image/svg+xml;
Keep gzip on as well — Nginx serves Brotli to clients that send Accept-Encoding: br and falls back to gzip otherwise.
sudo nginx -t && sudo nginx -s reload