nginx

Nginx Gzip Compression Configuration

Nginx gzip compression config to reduce response sizes for text-based assets with optimal compression levels.

Overview

Gzip compression reduces the size of HTTP responses, cutting bandwidth usage and improving page load times. Text-based formats like HTML, CSS, and JavaScript compress extremely well (often 60-80% size reduction). This configuration sets up gzip with sensible defaults.

Configuration

# /etc/nginx/conf.d/gzip.conf
# Include this file in your main nginx.conf http block

# Enable gzip compression
gzip on;

# Minimum file size to compress (smaller files aren't worth the CPU)
gzip_min_length 256;

# Compression level: 1 (fastest) to 9 (smallest)
# Level 4-6 offers the best balance of speed and compression
gzip_comp_level 5;

# Compress responses for all proxy requests
gzip_proxied any;

# Add Vary: Accept-Encoding header for proper caching
gzip_vary on;

# MIME types to compress (text-based formats only)
gzip_types
    text/plain                     # .txt files
    text/css                       # Stylesheets
    text/xml                       # XML documents
    text/javascript                # JavaScript (legacy MIME)
    application/javascript         # JavaScript (standard MIME)
    application/json               # JSON API responses
    application/xml                # XML API responses
    application/rss+xml            # RSS feeds
    application/atom+xml           # Atom feeds
    application/vnd.ms-fontobject  # EOT fonts
    font/opentype                  # OTF fonts
    font/ttf                       # TTF fonts
    image/svg+xml                  # SVG images
    image/x-icon                   # Favicons
    application/xhtml+xml          # XHTML
    application/manifest+json      # Web app manifests
    application/wasm;              # WebAssembly modules

# Number and size of compression buffers
gzip_buffers 16 8k;

# Compress responses for HTTP/1.1 and above
gzip_http_version 1.1;

# Do NOT compress already-compressed formats
# (images, videos, archives are already compressed)
# These are excluded by default since they're not in gzip_types

# Serve pre-compressed .gz files if available
gzip_static on;

# Disable gzip for old IE versions (IE6 and below)
gzip_disable "msie6";
# Example usage in a server block
server {
    listen 80;
    server_name example.com;

    # Gzip settings are inherited from http block (gzip.conf above)
    # You can override per-location if needed

    location /api/ {
        # API responses — compression helps with large JSON payloads
        proxy_pass http://backend;
        # gzip settings inherited from http context
    }

    location /assets/ {
        # Static assets — serve pre-compressed if available
        root /var/www;
        gzip_static on;     # Serve .gz files directly
        expires 1y;
    }

    location /streaming/ {
        # Disable gzip for streaming/SSE endpoints
        gzip off;
        proxy_pass http://backend;
        proxy_buffering off;
    }
}

Key Options Explained

  • gzip_comp_level 5 — Level 5 gives roughly 75% of the maximum compression at a fraction of the CPU cost of level 9. Above level 6, diminishing returns kick in hard.
  • gzip_min_length 256 — Files under 256 bytes may actually grow after gzip encoding due to header overhead. Skip them.
  • gzip_vary on — Adds Vary: Accept-Encoding to responses so CDNs and proxies cache compressed and uncompressed versions separately.
  • gzip_static on — If a pre-compressed file.js.gz exists alongside file.js, Nginx serves it directly without runtime compression. Build tools like Webpack and Vite can generate these.
  • gzip_proxied any — Compresses responses even when the request came through a proxy. Without this, proxied requests may skip compression.

Common Modifications

  • Brotli compression: Install the ngx_brotli module for better compression ratios. Add brotli on; brotli_types text/plain text/css application/javascript application/json image/svg+xml; alongside gzip settings.
  • Higher compression for APIs: Set gzip_comp_level 7 in API location blocks where large JSON responses benefit from smaller sizes.
  • Disable for specific paths: Add gzip off; inside location blocks for already-compressed content or streaming endpoints.
  • Pre-compress at build time: Use gzip -k -9 dist/**/*.{js,css,html} during deployment so gzip_static can serve optimal files without runtime cost.