Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for NGINX By James Joyner IV · · 10 min read

AI-Assisted NGINX Compression with gzip and Brotli

Set up NGINX response compression with AI: the right MIME types, sane compression levels, Vary headers, precompressed static files, and not compressing the uncompressible.

  • #nginx
  • #ai
  • #compression
  • #performance

Compression is one of the highest-leverage NGINX tweaks there is — a properly compressed HTML or JSON response is often a quarter of its original size — and it’s also where people quietly waste CPU compressing JPEGs and crank the level to 9 for a rounding-error gain. I’ve inherited configs that did both. AI is a solid drafting partner for compression because it knows which MIME types are worth compressing and the standard directive set, but the judgment calls — what level, what to exclude, whether Brotli is even available — are yours, and the failure modes are the kind that don’t error, they just waste resources.

This guide covers setting up gzip and Brotli sensibly in NGINX, with AI drafting and you deciding.

What compression buys and costs

Compression trades CPU for bandwidth. For text — HTML, CSS, JavaScript, JSON, SVG, XML — that’s a fantastic trade, because text compresses dramatically and the CPU cost is small. For already-compressed binary formats — JPEG, PNG, MP4, WOFF2 fonts, ZIP archives — it’s a bad trade: they barely shrink, and you’ve spent CPU for nothing. So the entire game is “compress text aggressively, never touch binary.” Everything else is tuning.

Drafting the gzip config

I start with gzip because it’s available everywhere. The prompt:

Draft an NGINX gzip config for a site serving HTML, JSON APIs, CSS, JS, and SVG. Set a sensible compression level (explain the choice), a min length, the right gzip_types, and gzip_vary. Explicitly do NOT compress images or already-compressed assets. Output config only.

The result, after review:

gzip on;

# Level 5 is the sweet spot: ~95% of the size reduction of level 9
# at a fraction of the CPU. Levels above 6 rarely earn their cost.
gzip_comp_level 5;

# Don't bother compressing tiny responses; the overhead isn't worth it.
gzip_min_length 256;

# Only text-based types. HTML is always compressed and isn't listed.
gzip_types
    text/plain text/css text/xml
    application/json application/javascript
    application/xml application/rss+xml
    image/svg+xml;

# Tell shared caches the response varies by Accept-Encoding.
gzip_vary on;

# Compress responses from proxied upstreams too (but see notes).
gzip_proxied any;

What I verify in any generated version:

  • The level. AI defaults to high levels surprisingly often. Level 5 or 6 captures nearly all the benefit; 9 burns noticeably more CPU for a sliver more savings. If the draft says gzip_comp_level 9, I push back.
  • gzip_vary on. Without it, a CDN or shared cache can hand a gzipped response to a client that didn’t request encoding, or cache one variant for everyone. This is a correctness issue, not just an optimization.
  • No image or video MIME types in gzip_types. SVG is text and belongs there; PNG and JPEG do not.

Adding Brotli — if you actually have it

Brotli compresses text noticeably better than gzip, especially for static assets, and every modern browser supports it. The catch: it is not in stock NGINX builds. You need the ngx_brotli module compiled in, and if it isn’t, adding brotli on; makes nginx -t fail outright. So the first step is always a build check, not config:

nginx -V 2>&1 | grep -o brotli || echo "no brotli module"

If that comes back empty, gzip is your answer and you skip the Brotli block entirely. AI will happily draft Brotli directives without knowing your build, so this check is on you. When the module is present, the block mirrors gzip:

brotli on;
brotli_comp_level 5;
brotli_types
    text/plain text/css text/xml
    application/json application/javascript
    image/svg+xml;

NGINX serves Brotli to clients that advertise br in Accept-Encoding and falls back to gzip for the rest, so running both is the normal setup, not an either/or.

Precompress static assets

For static files you control — your bundled JS and CSS — there’s a better option than compressing on every request: compress them once at build time and let NGINX serve the precompressed file directly. This spends zero request-time CPU.

# Serve a precompressed file.br / file.gz if it exists alongside the asset
brotli_static on;
gzip_static on;

With these on, a request for app.js checks for app.js.br (then app.js.gz) and serves it as-is when the client supports it. You generate the .br/.gz files in your build pipeline. This is the single biggest compression win for static-heavy sites, and AI often forgets to mention it unless you ask — so ask.

Validate, then prove the encoding

The config goes through the gate, and with Brotli the gate is doing real work — a missing module fails here:

sudo nginx -t
sudo nginx -s reload

Then prove compression actually happens, because nginx -t only confirms the config is valid, not that responses come back encoded:

# Ask for both encodings and check what came back
curl -s -H "Accept-Encoding: gzip, br" -I https://example.com/ | grep -i content-encoding
# Expect: content-encoding: br   (or gzip)

# Confirm an image is NOT compressed
curl -s -H "Accept-Encoding: gzip, br" -I https://example.com/logo.png | grep -i content-encoding
# Expect: no content-encoding header

The second check is the one people skip — it confirms you’re not wasting CPU on binary. If your PNG comes back with a content-encoding header, a stray MIME type sneaked into your types list.

Where AI fits

AI drafted the gzip and Brotli blocks, listed the right text MIME types, and explained the Vary header. What it didn’t do unprompted was pick a sane compression level over 9, check whether my build even had Brotli, or suggest precompressed static files — the three things that separate a good compression setup from a wasteful one. Draft with AI, validate with nginx -t, and curl both a text and a binary response to confirm you’re compressing exactly what you meant to.

More patterns in the AI for NGINX category. The gzip and Brotli compression prompt is the reusable version, and the performance tuning prompt in the prompt library covers the worker and keepalive settings that compound with compression.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.