Authoritative reference for gzip, rate limiting, and security header directives. Read →
Enable gzip to compress responses — typically 60-70% size reduction for HTML/CSS/JS:
# Add to nginx.conf http{} block or your server block
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_proxied any;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml;
Never gzip images (PNG, JPG, WebP) — they're already compressed. Gzip only compresses text-based content effectively.
# Cache static assets aggressively (they have hashed filenames)
location ~* \.(js|css|png|jpg|svg|ico|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Never cache HTML (it changes on every deploy)
location / {
add_header Cache-Control "no-cache, no-store, must-revalidate";
proxy_pass http://localhost:3000;
}
# Define rate limit zone (in http{} block)
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# Apply to location (allow burst of 20, then queue)
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://localhost:3000;
}
# Block IPs that exceed limits with 429
limit_req_status 429;
Rate limiting in Nginx doesn't replace application-level rate limiting in Redis. Use both: Nginx stops DDoS, Redis handles per-user API quotas.
# Add to your server block (these are the essentials)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Content Security Policy — tune per app
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;
# Hide Nginx version from attackers
server_tokens off;
# Prevent large request body attacks
client_max_body_size 10m; # Limit upload size (default 1m)
client_body_timeout 10s;
client_header_timeout 10s;
# Timeout for proxied requests
proxy_read_timeout 60s;
proxy_connect_timeout 10s;
# Keep connections alive (performance)
keepalive_timeout 65;
keepalive_requests 100;