Content-Encoding Negotiation
Content-Encoding compresses response bodies with gzip, brotli, or zstd based on client-advertised algorithms, trading CPU for transfer size on compressible text content.
Definition
Content-Encoding is a representation header naming the compression applied to the body, selected from the algorithms the client lists in Accept-Encoding. gzip is universal, brotli shrinks text further at higher CPU cost, and zstd offers tunable speed-to-ratio. Encoding is orthogonal to Transfer-Encoding and persists in caches with the representation.
Context and scope
Configured on web servers, CDNs, and API gateways for HTML, CSS, JavaScript, JSON, and SVG. Image and video formats are already compressed and re-compressing them wastes CPU.
Common misconceptions
- Compression always helps — already-compressed media gains nothing and burns CPU on both ends
- Brotli is simply better — its advantage appears at higher quality levels and costs meaningfully more CPU to encode
- Compressing is safe for all responses — streaming and SSE need flush-aware compression or latency spikes
Anti-patterns
- Enabling maximum-level brotli for dynamically generated responses on CPU-bound origins
- Compressing event streams without flushing per event, batching SSE messages into delayed bursts
- Serving different encodings without a strong Vary header, poisoning shared caches with mismatched bodies
Related concepts
Related examples
Authoritative source
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Encoding
What it is
The client advertises which decoders it supports; the server picks one and records it in Content-Encoding. The compressed bytes are what gets cached, so the encoding is part of the representation identity, which is why Vary matters. Compression shrinks text payloads by two-thirds or more, often the single cheapest performance win.
How it works
Accept-Encoding lists tokens with quality values; gzip, br, and zstd dominate. Servers choose per content type and size threshold. Dynamic compression happens per response and costs origin CPU, while precompressed assets can ship at maximum level for free. zstd supports streaming with explicit flush points for event streams.
When to use it
Compress all text: markup, styles, scripts, JSON, and fonts where applicable. Precompress static assets at the highest level. For streaming responses, verify that compression flushes align with event boundaries so time-to-first-event does not regress.
Pitfalls
Double compression of media wastes CPU and can grow files. Shared caches that ignore Vary serve brotli bodies to gzip-only clients, breaking pages. Breach-style attacks exploited compression plus reflection, so mixed secrets and reflected input in one compressed context deserve care.