Request and response header
< Content-Encoding: gzipContent-Encoding
Learn how Content-Encoding specifies compression algorithms (gzip, br, deflate) used to encode response bodies. Reduce bandwidth and improve load times.
- 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
- What is Content-Encoding?
- How It Works
- Common Encoding Types
- gzip
- br (Brotli)
- zstd (Zstandard)
- deflate
- identity
- Multiple Encodings
- Measure the savings on your own responses
- What Gets Compressed
- Server Configuration
- Apache
- Nginx
- Node.js (Express)
- Browser Support
- Security Considerations
- Getting Content-Encoding right
- Common Issues
- Related Headers
TL;DR: Names the compression applied to the response body (
gzip,br,zstd, rarelydeflate). The client undoes it before using the body. Servers should only pick an encoding the client listed inAccept-Encoding, and addVary: Accept-Encodingso 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
Related Headers
- Accept-Encoding - Client’s supported compression methods
- Content-Length - Size of compressed content
- Content-Type - Type of content being compressed
- Vary - Cache different compressed versions
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
Related
HTTP Compression: gzip, Brotli and Zstandard Setup
How HTTP compression works: Accept-Encoding negotiation, gzip vs Brotli vs zstd, nginx, Caddy, Express and Cloudflare config, BREACH, and measuring with curl.
Access-Control-Max-Age Header
Learn how Access-Control-Max-Age specifies how long browsers can cache CORS preflight results. Reduce preflight requests and improve cross-origin performance.
Early-Hints
Learn how 103 Early Hints allows servers to send preload hints while preparing the main response. Improve page load performance with early resource loading.
Link Header
Learn how the Link header provides resource hints and enables preloading of CSS, fonts, and scripts to improve page load performance and user experience.