Text compression: gzip, Brotli and Zstandard

Text compression shrinks HTML, CSS and JavaScript before they travel. How gzip, Brotli and Zstandard compare, how to check yours, and how to switch it on.

IntermediateHow-to8 min readUpdated October 30, 2026

In this guide
  1. What compression does
  2. What to compress, and what to leave alone
  3. gzip, Brotli and Zstandard
  4. Check whether it is on
  5. Turn it on
  6. Compress static files once
  7. What can go wrong
  8. Check your own page
  9. Sources

What compression does

Text repeats itself. The same tags, class names, keywords and property names appear again and again. A compression method replaces the repeats with short references, and the result unpacks to exactly the original file. Nothing is lost.

The server and the browser agree on a method in a short exchange:

  1. The browser asks for a file and lists the methods it can unpack in the Accept-Encoding request header. A current browser sends something like gzip, deflate, br, zstd.
  2. The server picks one method, compresses the file with it, and names it in the Content-Encoding response header.
  3. The server adds Vary: Accept-Encoding. That tells any cache in between to keep a separate copy for each method, so a packed file never reaches a client that cannot unpack it.
  4. The browser unpacks the file and uses it.

How much does it save? MDN says some documents shrink by up to 70%. For the HTML page, Lighthouse assumes a saving of about two thirds. The exact figure depends on the file, and a file that is already small has little to gain.

It matters most for the files the browser needs before it can show anything. The HTML and the stylesheets in the head arrive sooner when they are smaller, which helps First Contentful Paint and Largest Contentful Paint. The gain is biggest on slow connections, where every kilobyte takes longer.

What to compress, and what to leave alone

The rule is simple: compress text, and do not compress what is already packed by its own format.

File typeCompress?Why
HTML, CSS, JavaScript, JSON, XML, plain textYesPlain text with many repeats
SVG images and ICO iconsYesSVG is text; the Web Almanac counts both among the text files that benefit
TTF and OTF fontsYesThese older font formats are not compressed in themselves
WOFF2 fontsNoAlready compressed with Brotli (see web fonts)
JPEG, PNG, GIF, WebP, AVIFNoThe image format already compresses the data (see image formats)
MP4, WebM, MP3 and other audio and videoNoPacked by their codecs
ZIP and other archivesNoPacked already

Very small files are not worth it either. Servers such as Nginx have a minimum size setting for this reason, and Lighthouse ignores an HTML page when it expects to save less than 1,400 bytes.

gzip, Brotli and Zstandard

Three methods matter today. Each has its own value in the two headers.

gzipBrotliZstandard
Header valuegzipbrzstd
Browser supportEvery major browserChrome 50, Edge 15, Firefox 44, Safari 11Chrome 123, Edge 123, Firefox 126, Safari 26.3
File sizeThe baselineSmaller than gzipOften smaller than Brotli at the same processor cost
Speed to compressFaster than BrotliSlower than gzipBuilt for real-time compression
Best forThe fallback for everyoneStatic files and cacheable pagesSites behind a CDN that offers it

Some notes on the table:

The newer methods are spreading, led by CDNs. In the 2025 Web Almanac, requests answered by a CDN were 46% Brotli, 42% gzip and 12% Zstandard on mobile. Requests answered by the site's own server were 39% Brotli and 61% gzip.

Check whether it is on

You cannot see compression in the page. You have to look at the headers.

  1. Open the page in Chrome, press Ctrl+Shift+J (Cmd+Option+J on a Mac), and open the Network tab. Reload the page.
  2. Click the request for the page or for a stylesheet or script.
  3. In the Headers tab, find content-encoding under Response Headers. br, gzip or zstd means it is compressed. No such line means it is not.
  4. To compare sizes, switch on Use large request rows in the Network settings. The Size column then shows two values: the top one is the compressed size on the network, the bottom one the size after unpacking.

The same check from a terminal asks for Brotli and gzip and prints only the two headers that matter:

curl -s -o /dev/null -D - -H 'Accept-Encoding: br, gzip' https://example.com/ | grep -i -E '^(content-encoding|vary)'

Run it for the page, then for a CSS file and a JavaScript file. You want content-encoding on all three and vary: accept-encoding as well.

In the Lighthouse report that PageSpeed Insights shows, the Document request latency insight has a line that reads "Applies text compression" or "No compression applied". In Lighthouse 13.5 that check covers the HTML page only. Older versions listed every uncompressed text file under "Enable text compression". Use the Network panel for your CSS and JavaScript.

Turn it on

Look for the easy place first, because compression is often already on and you only need to check.

On WordPress, compression is normally a setting of the server or CDN, and some caching plugins have an option for it. Lighthouse's own advice for WordPress is to enable text compression in the web server configuration.

For Apache, the module mod_deflate does gzip, and mod_brotli does Brotli from version 2.4.26 on. A gzip setup for the common text types:

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json image/svg+xml
</IfModule>

For Nginx, gzip is built in but off until you switch it on. The type list adds to text/html, which is always compressed once gzip is on:

gzip on;
gzip_vary on;                 # adds Vary: Accept-Encoding
gzip_comp_level 5;            # 1 to 9: higher is smaller but uses more processor time
gzip_min_length 256;          # skip tiny responses
gzip_types text/css text/javascript application/javascript application/json image/svg+xml text/xml;

Brotli on Nginx needs an extra module. Check what your host or distribution provides before you compile anything.

Two details trip people up. The type list is matched against the type the server really sends, so a script sent as application/javascript is not covered by a list that only says text/javascript; list both. And Nginx does not compress a request that came through a proxy, which it recognizes by the Via request header, unless gzip_proxied allows it. If a CDN or proxy sits in front of Nginx and the files arrive unpacked, check that setting.

Compress static files once

Compressing on every request costs processor time. For files that do not change, such as the CSS and JavaScript from a build, compress them once at the highest level and store the packed copies next to the originals. The Apache documentation describes the idea: mod_deflate compresses again for each request, so serving pre-compressed files avoids that work. Nginx can serve a stored .gz file with its gzip_static setting, although that module is not built by default. The Brotli module for Nginx has a matching setting for .br files.

Many build tools and CDNs do this for you. The result is the smallest files at no cost per visit. Keep the dynamic pages, which are built for each visitor, at a moderate level. web.dev suggests Brotli level 4 (or gzip level 6) for pages compressed on request, and the strongest levels, Brotli 11 (or gzip 9), for static files.

What can go wrong

Check your own page

Run the free audit and look at Document request latency. If it says "No compression applied", the HTML page is going out unpacked, and turning compression on is one of the quickest fixes on the list. Then check your CSS and JavaScript files in the Network panel, because the report does not list them. In the Web Almanac's 2025 data, more than a quarter of pages still failed Lighthouse's text compression test, so this is a common gap. For the server settings behind a slow first response, see choosing web hosting for speed.

Sources

Start here

Free website audit

Live Google data for any public page: mobile and desktop.

Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it

Rather have this done for you? Speed optimization · Book a call

Related guides

All guides →