How does HTTP compression with gzip and Brotli work?
The browser lists the codings it can decode in Accept-Encoding (today gzip, deflate, br and often zstd); the server compresses the body with one of them and names it in Content-Encoding, and the browser decodes it before use. Brotli (RFC 7932) usually makes text smaller than gzip (RFC 1952). Text formats such as HTML, CSS, JavaScript and JSON shrink a lot, while images, video and fonts in WOFF2 are already compressed, and a compressed response should send Vary: Accept-Encoding so caches keep one copy per coding.
How to use Gzip / Brotli Checker
- Enter the final URL of the page, script, stylesheet or API response to test (redirects are not followed).
- Press Check compression.
- Read the Findings first, then the three requests: the Content-Encoding column shows which encodings the server really used.
- If text is served uncompressed or Vary is missing, enable compression or the Vary header on the server or CDN and check again.
Gzip / Brotli Checker features
- Sends three GET requests from the Mutqan server that differ only in Accept-Encoding — identity (no compression), gzip and br (Brotli) — and compares the answers side by side
- Shows, for each request, the HTTP status, the Content-Encoding the server chose, the Content-Length it declared, the bytes after decoding, the time to first byte and the total time
- Computes the gzip and Brotli savings only when that encoding really answered with a Content-Length, and says by name why a saving could not be measured (chunked transfer, a redirect, a refused request)
- Explains the result for the content type: a text response served uncompressed, an image or video that is already compressed, a server offering only gzip or only Brotli
- Checks that a compressed response sends Vary: Accept-Encoding, so shared caches keep a separate copy per encoding
- Flags a server that compresses even when asked not to, and a Brotli result larger than gzip
Inputs and outputs
Inputs
- URL to check — the final http:// or https:// address of the resource; a bare host name gets https:// added. Run the check again on the target if the URL redirects.
- Nothing else: the three Accept-Encoding values and the request headers are fixed.
Outputs
- Summary — whether gzip and Brotli are used, the saving of each when measurable, and the uncompressed size.
- Findings — what the answers mean for this content type, a missing Vary: Accept-Encoding, and small or already-compressed responses.
- The three requests — status, Content-Encoding, Content-Length, bytes after decoding and timing for identity, gzip and br; downloadable as CSV.
- Response — the URL, Content-Type and Vary header, and where the measurement was made; the notes explain every case that could not be measured.
Gzip / Brotli Checker example
A page served with gzip and with chunked Brotli
Input:
URL to check: https://www.example.com/Output:
gzip Used · Brotli Used · gzip saving 76.4 % · Brotli saving — (not measurable) · Uncompressed size 84210 B
identity → 200, no Content-Encoding, Content-Length 84210
gzip → 200, gzip, Content-Length 19870
br → 200, br, Content-Length not sent (chunked)
The server compresses with both Brotli and gzip, choosing by the Accept-Encoding the client sends.
The server compresses but does not send Vary: Accept-Encoding; a shared cache may hand the compressed copy to a client that cannot decode it.
The Brotli response was sent without Content-Length (chunked), so its compressed size is not reported.How to read the Gzip / Brotli Checker results
"Used" means the request that asked for that encoding got a 2xx answer with the matching Content-Encoding. "Not used" means it got a 2xx answer without it; "—" means it was not answered with 2xx, so nothing can be said.
A saving appears only when the compressed answer carried a Content-Length. "Not measurable" is not a failure of the site: many servers stream compressed responses in chunks, which is normal.
For HTML, CSS, JavaScript, JSON, XML and SVG, no compression at all is worth fixing. For JPEG, PNG, WebP, video, WOFF2 or ZIP, no compression is the correct choice.
Times are measured from the Mutqan server and include the first connection; compare the three only roughly, since one request may have warmed a cache for the next.
When to use Gzip / Brotli Checker
- After a server, CDN or framework change, confirm that HTML, scripts and stylesheets are still served compressed.
- Check that Brotli is really enabled on the CDN for your text assets, not just gzip.
- Investigate a slow page or a poor performance score that points at text compression.
- Verify that an API returns compressed JSON when the client asks for it, and that Vary: Accept-Encoding is set for caches.
Troubleshooting
- All three requests answer 301 or 302: the URL redirects and the checker does not follow redirects. The notes show the target; check that URL instead.
- gzip and Brotli are both "Not used" on a page your browser shows compressed: some servers compress only for certain User-Agents or after a first request has warmed a cache. Run the check again, and check the server's compression rules.
- The identity request also came back compressed: the server ignores Accept-Encoding: identity. Browsers always accept gzip, so this rarely matters, but clients that cannot decode it would fail.
- A refusal such as "This address cannot be reached from the Mutqan server": private and reserved addresses are never requested. Only public URLs can be checked.
Frequently asked questions about Gzip / Brotli Checker
How does the checker test compression?
It sends three GET requests that differ only in Accept-Encoding: identity (no compression), gzip and br (Brotli). A server that supports an encoding answers with the matching Content-Encoding header. Redirects are not followed, so run the check on the final URL.
Why is a saving sometimes not shown?
The Mutqan server runs on Cloudflare Workers, whose runtime decodes compressed bodies before the check sees them, so the compressed size can only come from the Content-Length header. A response sent in chunks without Content-Length has no reported compressed size, and the checker says so instead of estimating one.
Is Brotli better than gzip?
For text such as HTML, CSS and JavaScript, Brotli (RFC 7932) usually produces smaller files than gzip (RFC 1952) at comparable speed, and every current browser supports it over HTTPS. Servers commonly offer both and pick Brotli when the client lists br in Accept-Encoding.
Should images and videos be compressed too?
No. JPEG, PNG, WebP, AVIF, video, WOFF2 fonts and ZIP files are already compressed; gzip or Brotli would add work and save almost nothing. Compression matters for text formats: HTML, CSS, JavaScript, JSON, XML and SVG.
Why does Vary: Accept-Encoding matter?
A cache that stores a compressed answer must not hand it to a client that cannot decode it. Vary: Accept-Encoding tells shared caches to keep a separate copy per encoding; the checker warns when a compressed response does not send it.
Technical notes
HTTP content coding is defined in RFC 9110 §8.4: a client lists the codings it accepts in Accept-Encoding, and the server names the one it applied in Content-Encoding. gzip is the format of RFC 1952 and br the Brotli format of RFC 7932; "identity" means no coding at all.
POST /api/v1/internet/http/compression makes three GET requests with the fixed Mutqan header profile and Accept-Encoding set to identity, gzip and br, without following redirects. The Cloudflare Workers runtime decodes compressed bodies before the check reads them, so the compressed size is the Content-Length the server declared; when the body is chunked there is no such header and no saving is computed. Bodies are read up to 1 MiB.
The saving is 1 − compressed ÷ uncompressed, with the uncompressed size taken from the identity answer's Content-Length, or from its decoded body when the server compressed the identity request anyway or sent it chunked.
Limitations and methodology
Compressed sizes come only from the Content-Length the server declared; the Mutqan server never sees the compressed bytes themselves, so chunked responses have no measured saving.
Each encoding is requested once, from the Mutqan server on Cloudflare's network. A CDN may compress differently at other edges, for other clients or once its cache is warm.
Only gzip and Brotli are tested; Zstandard (zstd) and deflate are not requested, and at most 1 MiB of each body is read.
Security and privacy
The Mutqan server receives the URL, sends three fixed GET requests with none of your cookies or credentials, reads the bodies only to count their bytes, and stores nothing.
References
- RFC 9110: HTTP SemanticsThe meaning of HTTP methods, header fields, status codes and content negotiation, independent of the wire version.
- RFC 1952: GZIP file format specification version 4.3The gzip format: a header, DEFLATE-compressed data and a CRC-32 and length trailer — the format behind the gzip content coding of HTTP.
- RFC 7932: Brotli Compressed Data FormatThe Brotli format, registered for HTTP as the br content coding: LZ77 with Huffman coding, context modelling and a built-in dictionary of common web text.