HTTP Compression

HTTP compression reduces the size of data transferred between servers and clients. A client sends an Accept-Encoding header listing supported content codings. The server picks one, compresses the response body, and indicates the choice in a Content-Encoding header. This exchange is a form of proactive content negotiation.

Baseline

Brotli compression is widely available across all major browsers. Zstandard is newly available.

How content coding works

HTTP compression operates at the representation level. The server applies a content coding to the response body before transmission. The client reverses the coding after receiving the full response.

The Accept-Encoding request header lists acceptable codings with optional quality values:

Accept-Encoding: br, gzip;q=0.8, zstd;q=0.9

The server selects one coding and returns the compressed body with two key headers:

Vary header and caching

Servers returning different encodings based on the request must include Vary: Accept-Encoding in the response. Without this header, a cache stores one encoded variant and serves the cached variant to clients expecting a encoding or no encoding at all.

Content codings

The content coding framework defines registered codings. The IANA Content Coding Registry tracks all registered codings. The most common ones used in HTTP:

gzip

The gzip coding uses the GZIP file format , combining LZ77 and Huffman coding. Supported by every HTTP client and server. The gzip coding remains the most widely deployed content coding on the web.

br (Brotli)

The br coding uses the Brotli algorithm , developed by Google. Brotli achieves higher compression ratios than gzip at comparable decompression speeds. Brotli includes a built-in static dictionary of common web content patterns, an advantage for compressing HTML, CSS, and JavaScript.

All major browsers support Brotli over HTTPS connections.

zstd (Zstandard)

The zstd coding uses the Zstandard algorithm , developed at Facebook. Zstandard offers a wide range of compression levels, from fast modes exceeding gzip speed to high modes rivaling Brotli compression ratios. Zstandard decompression is fast regardless of the compression level used.

deflate

The deflate coding wraps a DEFLATE compressed stream inside the zlib format . Historical inconsistencies between implementations (some sent raw DEFLATE without the zlib wrapper) made deflate unreliable. Modern HTTP favors gzip or br instead.

compress

The compress coding uses adaptive Lempel-Ziv- Welch (LZW). Rarely encountered in modern HTTP.

identity

The identity coding means no transformation was applied. This value appears in Accept-Encoding to signal acceptance of uncompressed responses. A server is always allowed to send an uncompressed response, even when the client lists only compression codings.

Lossy vs. lossless compression

HTTP content coding is exclusively lossless. Every content coding registered for use with Content-Encoding (gzip, br, zstd, deflate) reconstructs the original bytes exactly on decompression.

Lossy compression exists in media formats like JPEG, MP3, and H.264. These formats are applied at the content creation stage, before HTTP transmission. A JPEG image served over HTTP is already lossy at the format level. Applying HTTP content coding (gzip or br) to a JPEG adds lossless compression on top, often with negligible size reduction, since the JPEG data is already compressed.

Skip compression for pre-compressed formats

Applying content coding to pre-compressed media (JPEG, PNG, MP4, WOFF2) wastes CPU cycles for minimal size savings. Server configurations often exclude these MIME types from compression.

End-to-end compression

End-to-end Compression compresses data at the origin and decompresses at the final client. Intermediaries such as proxies, load balancers, and CDNs pass the compressed body through without modification.

The negotiation flow:

  1. Client sends Accept-Encoding listing supported codings
  2. Server selects a coding and compresses the response body
  3. Server returns Content-Encoding and Vary: Accept-Encoding
  4. Client decompresses the body

This is the standard compression model in HTTP and the one most servers implement.

Hop-by-hop compression

Hop-by-hop compression uses Transfer-Encoding instead of Content-Encoding. The compression applies between individual hops (client to proxy, proxy to proxy, proxy to server) rather than across the entire path.

The client sends a TE header to indicate which transfer codings are acceptable. The receiving server or intermediary selects a coding and applies the compression for one hop. The next hop negotiates independently.

HTTP/2 restriction on TE

HTTP/2 restricts the TE header to the value trailers only. Hop-by-hop transfer coding compression is not available in HTTP/2 or HTTP/3.

Limited server support

Hop-by-hop compression is rarely implemented. Most servers and proxies use end-to-end content coding instead.

Example

A client requests an HTML page and lists four accepted codings in order of preference. The server selects gzip and returns the compressed response with the appropriate headers.

Request

GET /news.html HTTP/1.1
Host: www.example.re
Accept-Encoding: br, zstd, gzip, deflate

Response

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 5028
Vary: Accept-Encoding

<compressed body>

The Content-Length value (5028) represents the compressed size. The original uncompressed HTML is larger. The Vary: Accept-Encoding header tells caches to store separate variants for different encoding preferences.

A Brotli-compressed response from the same server to a client supporting br:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Encoding: br
Content-Length: 4211
Vary: Accept-Encoding

<compressed body>

SEO and compression

Search engine crawlers like Googlebot support gzip and Brotli. Compressed responses reduce crawl bandwidth consumption, allowing more pages to be fetched within a crawl budget. Bingbot sends Accept-Encoding: gzip, deflate.

Takeaway

HTTP compression reduces transfer sizes through lossless content codings negotiated between client and server via Accept-Encoding and Content-Encoding. Brotli and Zstandard offer better ratios than gzip, while gzip remains universally supported. Servers include Vary: Accept-Encoding to ensure caches serve the correct variant.

See also

Last updated: March 6, 2026