Compression Built Into the Protocol
Content encoding is compression applied to a response body before it is sent. The point is simple: a smaller payload spends less time on the wire, so the page arrives faster — particularly on slow or distant connections where every saved kilobyte counts. Because text is highly repetitive (think how often <div class= appears in a page), it compresses far more than already-dense data, which is why this technique targets text resources specifically.
The elegant part is that it is built into HTTP as a negotiation, handled entirely through two headers. Neither side assumes anything: the browser states what it can decode, and the server chooses from that list. The user sees nothing — just a page that loads quicker.
The Two-Header Handshake
The browser opens by listing the compression schemes it understands in the Accept-Encoding request header:
Accept-Encoding: gzip, br, zstd
The server picks one it also supports, compresses the body with it, and reports the choice in the Content-Encoding response header — alongside the Content-Type that still describes the underlying format:
Content-Type: text/html; charset=utf-8
Content-Encoding: br
The browser sees Content-Encoding: br, decompresses the Brotli-packed body, and then treats the result as the UTF-8 HTML the content type promised. If the browser had sent no Accept-Encoding, or the server supported none of the listed schemes, the body would simply arrive uncompressed — the negotiation always has a safe fallback.
Gzip, Brotli, and zstd
Three schemes cover almost all of today's traffic, and they trade off differently between how small they make a file and how much CPU they spend doing it.
| Scheme | Token | Character |
|---|---|---|
| gzip | gzip | The long-standing default — fast, universally supported, decades of compatibility. Excellent for compressing on the fly. |
| Brotli | br | Newer and built for the web; ships with a dictionary of common web text, so it usually beats gzip on HTML, CSS, and JS. High settings are slower, so it shines for static assets compressed once. |
| Zstandard | zstd | A modern scheme prized for an exceptional speed-to-ratio balance, increasingly supported by browsers and servers. |
The headline comparison most people want is gzip versus Brotli. For the same web file, Brotli typically produces a smaller result than gzip — often noticeably so on HTML and JavaScript — partly thanks to that built-in web dictionary, which gives it a head start on the boilerplate that appears on nearly every site. The catch is time: Brotli at its maximum level works harder than gzip, so squeezing the last few percent costs more CPU.
Compress Once, Serve Many — or Compress on the Fly
That speed trade-off resolves cleanly once you split content into two kinds. Static assets — your CSS bundle, your JavaScript, fonts — change rarely and are served to everyone. Compress them once at the highest Brotli level, cache the result, and every visitor gets the smallest possible file at no repeated cost. The slow compression happens a single time, off to the side.
Dynamic responses — a personalised page, a fresh API result — are generated per request and cannot be pre-compressed. Here you compress on the fly, and the right call is a faster, lower setting (gzip, or Brotli at a modest level) so the compression time does not eat the network savings. The general rule: maximum compression for things you build once, fast compression for things you build every time. This pairs naturally with caching — a compressed-and-cached asset is about as cheap as the web gets.
What Not to Compress
A common and costly mistake is compressing everything indiscriminately. Images (JPEG, PNG, WebP), video (MP4), and audio are already compressed by their own formats, which have wrung out the redundancy that gzip and Brotli look for. Running content encoding over them burns CPU for essentially zero gain — and can even add a few bytes of overhead, making the file marginally larger. Content encoding is for the text-based resources: HTML, CSS, JavaScript, JSON, SVG, XML, and font files. Media is left alone, relying on the compression baked into its format.
Two footnotes worth knowing. Content encoding is distinct from transfer encoding (such as chunked), which is about how a body is framed on the connection rather than how it is compressed. And HTTP/2 and HTTP/3 add header compression of their own — separate from this body compression — so that the headers themselves, not just the payload, travel efficiently. The principle runs all the way through: on the modern web, very little is sent at full size if it does not have to be.
Frequently Asked Questions
What is HTTP content encoding?
Compression applied to a response body before it is sent, so less data crosses the network. The browser advertises supported schemes in Accept-Encoding, the server compresses and names its choice in Content-Encoding, and the browser decompresses on arrival. It can shrink text files by 70–90%.
What is the difference between gzip and Brotli?
Both compress text, but Brotli usually produces smaller files for web content, helped by a built-in dictionary of common web text. Gzip is older, universal, and very fast. Brotli at high settings compresses more but takes longer, so it suits static assets compressed once and served many times.
Does compression help with images and video?
No — and you should not apply it. JPEG, PNG, MP4, and WebP are already compressed, so gzip or Brotli over them wastes CPU and can slightly enlarge them. Content encoding is for text: HTML, CSS, JavaScript, JSON, SVG, and fonts.
What is Accept-Encoding?
A request header in which the browser lists the compression schemes it can decode — gzip, br for Brotli, zstd. The server picks one it supports, compresses with it, and reports the choice in Content-Encoding. If none match, the response is sent uncompressed.
Does compression slow down the server?
It costs some CPU, but for text the network savings almost always outweigh it. Static files are compressed once at the highest setting and cached; dynamic responses are compressed at a lower, faster setting on the fly to balance CPU against bandwidth.