gzip and Static Performance
Introduction
gzip compresses text responses (HTML, CSS, JS, JSON) before sending them over the network—often cutting transfer size by 60–80%. Nginx can compress on the fly while serving static files. This chapter enables gzip safely, tunes which types compress, and touches other static performance defaults like sendfile.
Prerequisites
Enable gzip
Typically in http block (applies to all sites) or per server:
Code explanation:
gzip on— enable compression for eligible responsesgzip_vary on— addsVary: Accept-Encodingfor cachesgzip_comp_level 5— balance CPU vs ratio (1 fast, 9 smallest)gzip_min_length 256— skip tiny files where compression saves littlegzip_types— MIME types to compress;text/htmlcompresses by default even if omitted
Reload after edit:
sudo nginx -t && sudo systemctl reload nginxVerify Compression Works
curl -I -H "Accept-Encoding: gzip" http://127.0.0.1/style.cssLook for:
Content-Encoding: gzipWithout the header, response may be uncompressed for that request.
Compare sizes:
curl -s -o /dev/null -w '%{size_download}\n' http://127.0.0.1/app.js
curl -s -H "Accept-Encoding: gzip" -o /dev/null -w '%{size_download}\n' http://127.0.0.1/app.jsSecond number should be smaller for text files.
gzip and Precompressed Files
Some builds ship .gz alongside assets. Nginx can serve them with gzip_static:
location /assets/ {
gzip_static on;
}Requires file.css.gz next to file.css. Useful at scale; optional for learning projects.
Brotli (Awareness)
Brotli (br) often beats gzip but needs the ngx_brotli module or newer builds—not always in default distro packages. gzip alone is enough for most VPS setups; CDNs may add Brotli at the edge.
sendfile and TCP Options
Often already set in default nginx.conf:
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
}Code explanation:
sendfile on— efficient kernel-to-network file transfer for static filestcp_nopush— send headers in one packet when used with sendfiletcp_nodelay— reduce small packet delay for keepalive connections
Rarely change these on first deploy; verify defaults before tuning.
Static Performance Checklist
| Technique | Benefit |
|---|---|
| gzip / gzip_static | Smaller transfers for text |
| Long cache on hashed assets | Fewer repeat downloads |
| HTTP/2 (HTTPS chapter) | Multiplexing over one connection |
| Correct MIME types | Browser parses without fallback delays |
worker_processes auto | Use available CPU cores |
Avoid premature optimization—measure with browser DevTools Network tab and curl.
Combined server Example
For global gzip, move gzip directives to http { } once and drop duplication per site.
When Not to gzip
| Case | Reason |
|---|---|
| Already compressed images (PNG, JPEG, WebP) | Size may increase |
| Very small files | Overhead > savings |
| Streaming / SSE | Compression may buffer undesirably |
| CPU-saturated server | Lower gzip_comp_level or offload to CDN |
Warning
Do Not gzip HTTPS secrets
Compression + TLS on user-specific secrets historically related to BREACH class attacks on dynamic pages—static public assets are fine.
FAQ
gzip in server vs http block?
http — all virtual hosts. server — one site only. Prefer single definition in http.
Does gzip slow the server?
Uses CPU. On small VPS, level 5 is typical. Monitor load under traffic.
Will gzip break old browsers?
Modern clients send Accept-Encoding: gzip. Ancient clients get uncompressed responses.
CDN gzip vs Nginx gzip?
Avoid double compression—either origin or CDN compresses, not both unknowingly.
How does this relate to Vite build?
Vite minifies JS/CSS; Nginx gzip compresses at transfer time—complementary steps.
worker_connections and performance?
Raise in events { } when handling many concurrent clients—advanced tuning; defaults suffice for learning.