Nginx Compression Configuration Guide
Enable gzip, Brotli, and zstd compression for optimal performance
Quick Start: Basic Gzip Configuration
Add this to your nginx.conf file in the http block for immediate compression benefits:
http {
# Enable gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml+rss
application/xhtml+xml
application/x-font-ttf
application/x-font-opentype
application/vnd.ms-fontobject
image/svg+xml
image/x-icon;
gzip_min_length 1000;
gzip_disable "msie6";
}
Verify Configuration
# Test configuration
nginx -t
# Reload Nginx
nginx -s reload
# Test compression
curl -H "Accept-Encoding: gzip" -I https://yourdomain.com
Gzip Configuration Options Explained
gzip on/off
Enables or disables gzip compression
gzip on;
gzip_comp_level
Compression level 1-9. Level 6 is optimal for most cases
gzip_comp_level 6;
gzip_min_length
Minimum file size to compress (in bytes)
gzip_min_length 1000;
gzip_vary
Adds "Vary: Accept-Encoding" header
gzip_vary on;
gzip_proxied
Compress responses for proxied requests
gzip_proxied any;
gzip_types
MIME types to compress
gzip_types text/css;
Advanced: Brotli Compression
Brotli provides 20-26% better compression than gzip. Here's how to enable it:
1. Install Brotli Module
# For Ubuntu/Debian
apt-get install nginx-module-brotli
# For CentOS/RHEL
yum install nginx-module-brotli
# Or compile from source
git clone https://github.com/google/ngx_brotli.git
cd nginx-1.x.x
./configure --add-dynamic-module=../ngx_brotli
make modules
2. Load Brotli Modules
# Add to top of nginx.conf
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
3. Configure Brotli
http {
# Brotli Settings
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml+rss
application/xhtml+xml
application/x-font-ttf
application/x-font-opentype
application/vnd.ms-fontobject
image/svg+xml
image/x-icon;
# Keep gzip as fallback
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types $brotli_types;
}
Static Pre-compression
Serve pre-compressed files to save CPU cycles:
Enable Static Gzip
location / {
gzip_static on;
brotli_static on;
try_files $uri $uri/ =404;
}
Pre-compress Files
# Gzip all static files
find /var/www/html -type f \( -name "*.html" -o -name "*.css" -o -name "*.js" \) \
-exec gzip -9 -k {} \;
# Brotli compress all static files
find /var/www/html -type f \( -name "*.html" -o -name "*.css" -o -name "*.js" \) \
-exec brotli -q 11 -k {} \;
Automated Pre-compression Script
#!/bin/bash
# precompress.sh - Run after deployment
WEBROOT="/var/www/html"
FILETYPES="html css js json xml svg"
for type in $FILETYPES; do
echo "Compressing .$type files..."
find "$WEBROOT" -name "*.$type" -type f | while read file; do
# Skip if already compressed
[ -f "$file.gz" ] || gzip -9 -k "$file"
[ -f "$file.br" ] || brotli -q 11 -k "$file"
done
done
echo "Pre-compression complete!"
Location-Specific Compression
Fine-tune compression for different content types:
API Endpoints
location /api/ {
# Lower compression for dynamic content
gzip_comp_level 1;
brotli_comp_level 1;
# Compress JSON responses
gzip_types application/json;
brotli_types application/json;
}
Static Assets
location ~* \.(css|js|html|xml)$ {
# Higher compression for static files
gzip_comp_level 9;
brotli_comp_level 6;
# Serve pre-compressed if available
gzip_static on;
brotli_static on;
# Cache headers
expires 1y;
add_header Cache-Control "public, immutable";
}
Images and Binary Files
location ~* \.(jpg|jpeg|png|gif|ico|webp|woff|woff2)$ {
# Don't compress already compressed formats
gzip off;
brotli off;
expires 1y;
add_header Cache-Control "public, immutable";
}
Performance Optimization Tips
Buffer Sizes
Optimize compression buffers for your workload:
gzip_buffers 16 8k;
brotli_window 512k;
CPU vs Compression
Balance CPU usage with compression ratio:
- Dynamic content: Level 1-4
- Static content: Level 5-6
- Pre-compressed: Level 9-11
Monitoring
Track compression effectiveness:
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /var/log/nginx/compression.log compression;
Complete Production Configuration
Here's a comprehensive Nginx compression configuration for production:
# Load Brotli modules (if installed)
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
http {
# Gzip Settings
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_disable "msie6";
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types
text/plain
text/css
text/xml
text/javascript
text/x-component
text/x-json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/xml+rss
application/xhtml+xml
application/x-font-ttf
application/x-font-opentype
application/vnd.ms-fontobject
font/opentype
image/svg+xml
image/x-icon;
# Brotli Settings
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types $gzip_types;
# Server configuration
server {
listen 443 ssl http2;
server_name example.com;
# SSL configuration (required for Brotli)
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Root directory
root /var/www/html;
# Default location
location / {
try_files $uri $uri/ =404;
# Enable pre-compressed file serving
gzip_static on;
brotli_static on;
}
# API endpoints - fast compression
location /api/ {
gzip_comp_level 1;
brotli_comp_level 1;
proxy_pass http://backend;
proxy_set_header Accept-Encoding "";
}
# Static assets - maximum compression
location ~* \.(css|js|html|xml|json|svg)$ {
gzip_comp_level 9;
brotli_comp_level 6;
gzip_static on;
brotli_static on;
expires 1y;
add_header Cache-Control "public, immutable";
}
# Already compressed formats
location ~* \.(jpg|jpeg|png|gif|webp|ico|woff|woff2|ttf|otf|eot|mp4|webm|zip|gz|br)$ {
gzip off;
brotli off;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}
Troubleshooting Common Issues
Compression Not Working
- Check if module is loaded:
nginx -V 2>&1 | grep -o with-http_gzip_module
- Verify MIME types are correct
- Ensure file size is above gzip_min_length
- Check for conflicting headers from upstream
High CPU Usage
- Lower compression levels for dynamic content
- Use pre-compressed files for static assets
- Implement caching to reduce compression frequency
- Consider upgrading server resources
Testing Commands
# Check if gzip is working
curl -H "Accept-Encoding: gzip" -I https://example.com/style.css | grep -i content-encoding
# Check if Brotli is working
curl -H "Accept-Encoding: br" -I https://example.com/style.css | grep -i content-encoding
# Compare file sizes
curl -s -H "Accept-Encoding: identity" https://example.com/app.js | wc -c
curl -s -H "Accept-Encoding: gzip" https://example.com/app.js | wc -c
curl -s -H "Accept-Encoding: br" https://example.com/app.js | wc -c
Next Steps
Now that you've configured compression on Nginx, explore these related topics: