Text compression, and the responses that miss out
Text compresses by roughly three quarters and switching it on is one line. Which is why the interesting question is not whether you have it, but which of your responses are quietly going out uncompressed anyway.
The short answer
Text compresses by roughly 70 to 90 percent, so HTML, CSS, JavaScript, JSON and SVG should never be served uncompressed. Brotli beats gzip by a further 15 to 20 percent on the same content. Images and video are already compressed and gain nothing, which is why the assets people miss are usually JSON APIs and SVG.
What compresses, and by how much
Compression works on repetition, so anything with structure gains enormously and anything already compressed gains nothing. The rough figures are stable enough to plan with.
type typical saving worth compressing?
----------------------- --------------- -----------------------------
HTML 70 to 80% yes, always
CSS 75 to 85% yes, always
JavaScript 65 to 75% yes, always
JSON and API responses 80 to 90% yes, and often forgotten
SVG 60 to 70% yes, and usually missed
plain text, XML 70 to 80% yes, sitemaps included
JPEG, PNG, WebP, AVIF 0 to 2% no. already compressed
MP4, WOFF2 0 to 1% no. wastes CPU on both ends
PDF 0 to 10% usually not worth itTwo rows are the ones this check tends to find. SVG is text and it is served as an image, so asset pipelines that decide what to compress by looking at the type prefix skip it. And JSON from an API is frequently served by a different layer to the one compressing your pages, so a site whose HTML is compressed can be shipping uncompressed payloads that are larger than the document.
On the algorithms: gzip is universal and fine. brotli saves a further 15 to 20 percent on text and is supported everywhere that matters. Both are negotiated by the client through the Accept-Encoding request header, so serving both and letting the browser choose is the normal arrangement rather than a decision.
Where compression goes missing
Almost nobody has compression switched off entirely. What sites have is a gap, and the gaps are predictable.
- A type list that has not been updated. The server compresses a named set of content types, and anything outside the list is served raw. The list was written before
application/json,image/svg+xmlandapplication/manifest+jsonmattered. - A minimum size threshold set too high. Reasonable in principle, since compressing 200 bytes costs more than it saves. Set at 20KB it excludes most of your CSS and every API response.
- A proxy that strips the header. The origin compresses, something in the middle decompresses to inspect and forgets to recompress. This is the hardest one to diagnose because the configuration you are looking at is correct.
- Assets on a different host. Your pages come from a CDN with compression on, your uploads come from object storage with nothing configured, and the second is where the volume is.
- Responses that opt out. Streamed responses, server-sent events and anything that sets its own encoding. Sometimes deliberate, and worth knowing which of yours are.
The pattern to notice: every one of these produces a site where the home page is compressed and something else is not. Testing one URL and concluding the site is fine is the mistake this check exists to correct.
Two requests, and the difference between them
Measuring this means asking for the same URL twice: once declaring that you accept compressed responses, and once not, then comparing the sizes that come back. A single fetch gives one of those two numbers, and one number cannot express a ratio.
This one needs the full crawl
Measuring this means requesting the same URL twice, once declaring support for compression and once not, then comparing the sizes that come back.
The instant search on this site audits a single page, so rather than show you a verdict it cannot support, this guide sends you to the place the check actually runs.
The two-request version is in the last section of this guide, and it is short enough to run against a handful of your own URLs right now.
Does this affect AI search?
Indirectly, through the same mechanism as everything about delivery: what arrives, and how quickly. Nothing reads whether a response was compressed, and no assessment of your content is affected by the encoding it travelled in.
There is one specific consequence worth naming. Clients that fetch pages programmatically often operate under a timeout, and some of them under a size limit. A large uncompressed document is slower to transfer and closer to whatever ceiling the client has, which makes a truncated or abandoned fetch marginally more likely. That is a real effect at the tail rather than a general one.
The honest position: compress your text because it makes your site faster for people and cheaper to serve. The machine-reader argument is a rounding error next to those two, and presenting it as more would be inventing a mechanism.
Why a setting nobody argues about is Important
Not because the absence is catastrophic. An uncompressed site works: pages load, crawlers fetch them, nothing is excluded, which keeps it clear of the Critical band.
It earns Important on the size of the effect against the size of the change. Cutting the transfer weight of every text response by three quarters is one of the largest performance improvements available anywhere, and the change is a configuration line with no code, no content and no judgement. Nothing else in this audit has that ratio.
The rating also accounts for who pays when it is missing. Compression matters most on a slow connection and a cheap device, which is to say it matters most for the visitors least able to absorb the cost. A finding that is free to fix and lands hardest on the people with the least bandwidth is not a refinement.
Measuring the ratio on your own responses
One function, run against the URLs that carry your weight: a page, a stylesheet, a bundle, an SVG, an API response.
ratio() {
raw=$(curl -s -o /dev/null -H 'Accept-Encoding: identity' -w '%{size_download}' "$1")
br=$(curl -s -o /dev/null -H 'Accept-Encoding: br, gzip' -w '%{size_download}' "$1")
enc=$(curl -s -I -H 'Accept-Encoding: br, gzip' "$1" \
| grep -i '^content-encoding:' | cut -d' ' -f2 | tr -d '\r')
if [ "$raw" -gt 0 ] 2>/dev/null; then
printf '%-46s %7s -> %7s %3s%% %s\n' \
"$1" "$raw" "$br" "$(( 100 - br * 100 / raw ))" "${enc:-NONE}"
fi
}
ratio https://example.com/
ratio https://example.com/assets/app.css
ratio https://example.com/assets/app.js
ratio https://example.com/icons/logo.svg
ratio https://example.com/api/products
ratio https://example.com/sitemap.xmlA saving near zero with an encoding of NONE is an uncompressed response. Read the list rather than the first row: the interesting output is almost always the SVG or the API endpoint rather than the page, because the page is the one somebody checked when they configured this.
Then look at what compression cannot help with.
On most pages the images are the weight, and they are already compressed. Once your text responses are gzipped, the remaining performance work is image formats, image dimensions and how much JavaScript you ship, and no amount of encoding touches any of those.
The neighbouring check on caching is the other half of this one, and it is worth more on a repeat visit than compression is: a cached asset transfers nothing at all, at any compression ratio.
Questions this check raises
- Should I use gzip or brotli?
- Both, negotiated by the client. Brotli compresses text 15 to 20 percent better than gzip at comparable settings and is supported by every current browser; gzip is the fallback for anything that does not advertise brotli. Every serious CDN does this automatically.
- Which files should not be compressed?
- Anything already compressed: JPEG, PNG, WebP, AVIF, MP4, and most font formats. Recompressing them costs CPU and gains a fraction of a percent, and in some cases makes the file marginally larger.
- Where does compression usually go missing?
- On the responses nobody looks at. HTML and CSS are almost always covered because they are what the default configuration lists. JSON API responses, SVG served from an assets path, and files coming from a second origin or a legacy server routinely are not.