How HTTP Works

Request and response header

< Content-Encoding: gzip

Content-Encoding

Learn how Content-Encoding specifies compression algorithms (gzip, br, deflate) used to encode response bodies. Reduce bandwidth and improve load times.

Reviewed 4 min readintermediate2 sourcesTry itMarkdown
Direction
Request and response
Category
Representation
Spec
RFC 9110 §8.4
JS can set it
Yes
CORS-safelisted
No: may trigger a preflight
On this page

TL;DR: Names the compression applied to the response body (gzip, br, zstd, rarely deflate). The client undoes it before using the body. Servers should only pick an encoding the client listed in Accept-Encoding, and add Vary: Accept-Encoding so caches keep the variants apart.

What is Content-Encoding?

Content-Encoding tells the browser how the response body has been compressed or encoded. It’s like a label on a compressed file that says “this was zipped with gzip” so the browser knows how to decompress it.

Text formats such as HTML, CSS, JavaScript and JSON usually shrink a lot; how much depends on the content, so measure your own responses (see below). The HTTP compression guide covers choosing between gzip, Brotli and zstd in depth.

How It Works

1. Browser requests with compression support:

GET /style.css HTTP/1.1
Host: example.com
Accept-Encoding: gzip, deflate, br

2. Server compresses response and adds header:

HTTP/1.1 200 OK
Content-Type: text/css
Content-Encoding: gzip
Content-Length: 1234

[compressed CSS data]

3. Browser automatically decompresses the response before using it.

Common Encoding Types

gzip

Most widely supported compression:

Content-Encoding: gzip
  • Supported by all modern browsers
  • Good compression on text at low CPU cost
  • Fast compression/decompression

br (Brotli)

Modern compression algorithm:

Content-Encoding: br
  • Usually smaller output than gzip on text
  • Supported by all current browsers
  • High levels are slow to compress, so large static files are often compressed once at build time

zstd (Zstandard)

Content-Encoding: zstd
  • Defined for HTTP in RFC 8878
  • Supported in Chrome and Edge 123+ and Firefox 126+; Safari support is partial (see the compression guide for details as of October 2026)
  • Fast to compress, which suits dynamic responses

deflate

Older compression method:

Content-Encoding: deflate
  • Less efficient than gzip
  • Rarely used today

identity

No compression (default):

Content-Encoding: identity
  • Usually omitted when no compression is used

Multiple Encodings

You can apply multiple encodings in order:

Content-Encoding: gzip, deflate

Browser decompresses in reverse order: deflate first, then gzip.

Measure the savings on your own responses

Compression ratios depend on the content, so check your real responses instead of trusting a rule of thumb:

for enc in identity gzip br zstd; do
  printf '%-8s ' "$enc"
  curl -s -H "Accept-Encoding: $enc" -o /dev/null -w '%{size_download} bytes\n' https://example.com/app.js
done

If every line shows the same size, the server ignored the encoding you asked for.

What Gets Compressed

✅ Compress these:

  • HTML, CSS, JavaScript
  • JSON, XML, SVG
  • Text files, and TTF/OTF fonts (WOFF2 is already Brotli-compressed)
  • Any text-based content

❌ Don’t compress these:

  • Images (JPEG, PNG, WebP) - already compressed
  • Videos (MP4, WebM) - already compressed
  • Audio files (MP3, AAC) - already compressed
  • Already compressed files (ZIP, GZIP)

Server Configuration

Apache

# Enable gzip compression
LoadModule deflate_module modules/mod_deflate.so

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/css text/javascript
    AddOutputFilterByType DEFLATE application/javascript application/json
</IfModule>

Nginx

# Enable gzip compression
gzip on;
gzip_types text/css text/javascript application/javascript application/json;
gzip_min_length 1000;

Node.js (Express)

const compression = require('compression')
app.use(compression())

Browser Support

  • gzip: every browser and HTTP client
  • br: all current browsers
  • zstd: Chrome and Edge 123+, Firefox 126+; Safari partial
  • deflate: accepted widely but rarely used, partly because early implementations disagreed on whether it meant raw DEFLATE or zlib-wrapped data

Because a server should only send an encoding the client listed in Accept-Encoding, enabling a newer one does not break older clients as long as gzip stays on.

Security Considerations

BREACH Attack: Compression can leak information when:

  • Response contains user secrets (CSRF tokens)
  • Response reflects user input
  • Response is compressed

Mitigation:

  • Don’t compress responses with secrets
  • Use random padding
  • Separate secret data from user input

Getting Content-Encoding right

1. Always compress text-based content:

Content-Encoding: gzip

2. Use Brotli for modern browsers:

Content-Encoding: br

3. Set minimum file size threshold:

Only compress files > 1KB

4. Don’t compress already-compressed files:

Skip: .jpg, .png, .mp4, .zip

5. Check what you actually send:

curl -sI -H 'Accept-Encoding: br, gzip' https://example.com/ | grep -i -E 'content-encoding|vary'

Common Issues

Problem: Content appears garbled Solution: Server sent compressed data but forgot Content-Encoding header

Problem: Slow compression Solution: Use faster compression levels or cache compressed versions

Problem: Double compression Solution: Don’t compress already-compressed files

Frequently asked questions

What is Content-Encoding?

Content-Encoding indicates what compression was applied to the response body. Common values are gzip, br (Brotli), and deflate. Clients must decompress before using the content.

What is the difference between Content-Encoding and Transfer-Encoding?

Content-Encoding is a property of the resource itself. Transfer-Encoding is about how data is transferred. Content-Encoding persists if cached; Transfer-Encoding does not.

Which compression should I use?

Brotli (br) offers best compression for text. Gzip is universally supported. Use Brotli for modern browsers, gzip as fallback. Check Accept-Encoding to choose.

How do I enable compression?

Configure your server or CDN. Nginx uses gzip_types, Apache uses mod_deflate. Most CDNs compress automatically. Only compress text formats, not already-compressed files like images.

Sources

  1. MDN Web Docs: Content-Encodingdeveloper.mozilla.org
  2. RFC 9110: Content-Encodingrfc-editor.org

Keep going

Browse /search