curl --compressed: request gzip, br or zstd and decompress the response
- tool
- HTTP
- command
- curl
- flag
- --compressed
- default
- off (curl sends no Accept-Encoding header, and servers that follow RFC 9110 send the body uncompressed)
curl --compressed URL adds an Accept-Encoding header listing every compression algorithm the curl build supports and transparently decompresses the response, so the output is the same as without compression but fewer bytes cross the network. Without the option curl asks for nothing, so a well-behaved server answers uncompressed. Use it to see what a browser actually receives, to test that a server or CDN compresses responses, and to save bandwidth on large text downloads.
Without and with --compressed
A local server compresses only when the request asks for gzip. %{size_download} reports the bytes received on the wire:
cat > server.js <<'EOF'
const http = require('http'), zlib = require('zlib');
const body = JSON.stringify({ items: Array.from({ length: 50 }, (_, i) => ({ id: i, name: 'item ' + i })) }) + '\n';
http.createServer((req, res) => {
res.setHeader('Vary', 'Accept-Encoding');
if (/\bgzip\b/.test(req.headers['accept-encoding'] || '')) {
res.setHeader('Content-Encoding', 'gzip');
return res.end(zlib.gzipSync(body));
}
res.end(body);
}).listen(5414, '127.0.0.1');
setTimeout(() => process.exit(0), 6000);
EOF
node server.js &
sleep 1
curl -s -o plain.json -w 'without: %{size_download} bytes received\n' http://127.0.0.1:5414/
curl -s --compressed -o comp.json -w 'with: %{size_download} bytes received\n' http://127.0.0.1:5414/
cmp plain.json comp.json && echo "saved files are identical"
curl -s -H 'Accept-Encoding: gzip' http://127.0.0.1:5414/ | head -c 2 | od -An -tx1
waitOutput
without: 1342 bytes received with: 278 bytes received saved files are identical 1f 8b
With --compressed the server sent 278 gzip bytes instead of 1,342, and curl wrote the same decompressed JSON. The last line shows the trap: setting Accept-Encoding: gzip by hand makes the server compress, but curl does not decompress, so the output starts with the gzip magic bytes 1f 8b.
What curl sends
The header depends on the libraries curl was built with. Check curl -V: libz enables deflate, gzip, brotli adds br, zstd adds zstd. A full build sends Accept-Encoding: deflate, gzip, br, zstd.
| Request | Server sends | curl writes |
|---|---|---|
| No option | Identity (uncompressed), per RFC 9110 | The body as received |
| --compressed | One of the listed encodings, or identity | The decompressed body |
| -H "Accept-Encoding: gzip" | gzip | Compressed bytes; nothing is decoded |
| --compressed with an unsupported server encoding | For example br on a build without brotli | curl fails with exit code 61 (CURLE_BAD_CONTENT_ENCODING) |
Checking that a server compresses
Look at the response headers rather than the body: curl -s --compressed -o /dev/null -D - URL and check for Content-Encoding and Vary: Accept-Encoding. Vary tells caches to store one copy per encoding; without it a proxy may serve gzip to a client that cannot decode it. See show HTTP response headers for the header options.
Pitfalls
- Content-Length is the compressed size. With
--compressedtheContent-Lengthheader (and%{size_download}) count encoded bytes, not the size of the file you get. -rranges apply to the encoded body. Combining--compressedwith a byte range asks for a slice of the compressed stream, which usually cannot be decoded on its own.- Transfer-Encoding is different.
--tr-encodingasks for hop-by-hop compressed transfer encoding, which few servers support;--compressedis the content encoding every web server and CDN implements. - ETags may change. Servers often send a different (weak) ETag for compressed variants, which matters for conditional requests.
FAQ
Why does curl print binary garbage instead of JSON?
The server sent a compressed body (Content-Encoding: gzip) even though curl did not ask for it, or you added an Accept-Encoding header by hand. Use --compressed instead of the manual header so curl also decompresses the body.
Which encodings does --compressed request?
Only those the curl build supports. A build with zlib, brotli and zstd sends Accept-Encoding: deflate, gzip, br, zstd; curl -V lists them in the Features line (libz, brotli, zstd).
Does --compressed make the download smaller on disk?
No. The transfer over the network is smaller, but curl writes the decompressed body, so the saved file is identical to what an uncompressed request would give.