Compress & Decompress

Online Zlib, Gzip, Deflate and Brotli compression and decompression. Compress text to Hex or Base64, all processed locally in your browser with no upload.

Compress Decompress
Zlib Gzip Deflate Brotli
Ctrl/⌘ + Enter to run
Error

Description:

Compression is not "smaller is better": each lossless algorithm has its own wrapper cost

Zlib, Gzip, Deflate and Brotli are all lossless compression algorithms: decompression restores every original byte exactly. They all share the Deflate core (LZ77 + Huffman) but differ in wrapper format and use case. One often-overlooked fact: the compression ratio depends not only on the algorithm but also on how redundant the input is and on the fixed overhead of the wrapper — for very short text, Gzip's 18-byte header/footer can make the result larger than the original. The rest of this page breaks down the four algorithms' specs, level trade-offs, compressibility rules and the real output of the default input, all driven by measured numbers. Unless noted otherwise, every figure below is produced by the same compression algorithms as this tool (Node zlib, which corresponds to fflate's Deflate/Zlib, Node's Gzip, and Brotli).

Table 1: specifications and wrapper overhead of the four algorithms

AlgorithmStandardCoreWrapper overhead (fixed bytes vs raw Deflate)ChecksumTypical use
DeflateRFC 1951LZ77 + Huffman0 bytes (raw stream, no header/footer)nonekernel of Zlib / Gzip, internal transfer
ZlibRFC 1950Deflate+6 bytes (2-byte header + 4-byte Adler-32 trailer)Adler-32HTTP compression, PNG, Git objects
GzipRFC 1952Deflate+18 bytes (10-byte header + 8-byte CRC-32 / ISIZE trailer)CRC-32.gz files, server response compression
BrotliRFC 7932context modeling + LZ77 + Huffman1–2 byte stream header (window bits) + ISLAST marker; no standalone checksum fieldrelies on transportweb fonts, static assets (Content-Encoding: br)

The "wrapper overhead" column is verified by this tool's own algorithms: on the same input, Zlib output is exactly 6 bytes larger than raw Deflate and Gzip is 18 bytes larger, matching the RFC-defined wrapper lengths. Brotli usually beats raw Deflate because its algorithm is stronger, so it is measured by volume rather than a fixed overhead. To strip tags and get clean prose before compressing, pair it with the HTML stripper; to estimate the input size first, use the word counter to check byte counts.

Table 2: volume vs. speed trade-off across levels 1–9 (Brotli to 11)

The level only controls "how hard compression tries": higher levels shrink slightly more but take noticeably longer. Measured on a ~13 KB HTML/CSS/JSON sample with reasonable repetition (not an extreme stress test), Gzip at levels 1–9 and Brotli at levels 1–11. Volume and saved % are deterministic; speed is the median of many runs on one reference machine (relative only):

LevelGzip bytesGzip savedGzip ms/MBBrotli bytesBrotli savedBrotli ms/MB
1161687.6%2147788.6%2
2160087.7%8130290.0%3
3155788.0%7125590.3%10
4156787.9%4116591.0%16
5152588.3%4110491.5%30
6152688.2%4110491.5%46
7151488.3%5110191.5%96
8151488.3%5110191.5%114
9151488.3%5109691.6%127
10———102692.1%209
11———98292.4%531

Note: speed varies with device and input and is shown only to reveal the relative trend. The takeaway is clear: Gzip levels 1–9 barely move in volume (all between 1514 and 1616 bytes) and stay very fast; Brotli from level 1 to 11 only cuts another ~4 percentage points yet its speed drops from about 2 ms/MB to about 531 ms/MB (roughly 300×). That is why Brotli levels 5–6 are the usual price/performance sweet spot for static assets, and going higher mostly trades time for almost unchanged bytes. Like the text encodings of compressed output, URL encoding is another encoding built to carry binary safely inside text.

Table 3: compressibility rules across text types

Compression works best on repetitive, redundant text and barely touches already-compressed or random data. Below, Gzip measured by this tool on six typical inputs (sample size in the "raw bytes" column):

Text typeRaw bytesGzip bytesSavedPattern
English prose112518583.6%highly redundant, compresses well
HTML page225443680.7%repeated tags, mid-to-high ratio
JSON config540175586.0%repeated keys, high ratio
Server log420017595.8%highly uniform lines, very high ratio
Already-compressed (simulated JPEG / MP3)2000020028-0.1%already compressed, no gain, slight growth
Base64 text266682011124.6%encoding removed most redundancy, little left

As a rule of thumb, natural English prose compressed with Gzip typically shrinks to 20%–30% of the original (i.e. 70%–80% saved), matching the 83.6% result for English prose above; JPEG, MP3 and ZIP are already compressed and gain almost nothing. For more on cleaning text before compressing, see the blog text cleaner guide.

Table 4: default-input before/after, measured with this tool's output convention

The table strictly uses this tool's default demo text (250 bytes) and its output convention (compressed volume includes each algorithm's wrapper; saved = 1 − compressed bytes / raw bytes), plus the text-encoded lengths of Base64 / Hex:

AlgorithmRaw bytesCompressed bytesSavedBase64 lengthHex length
Gzip (default)25018824.8%252376
Zlib25017629.6%236352
Deflate25017032.0%228340
Brotli25016733.2%224334

Note: the default demo text is short, and with Gzip you get 188 bytes (saving 24.8%) — already positive here because English text is more redundant than the equivalent Chinese sample. But the 18-byte Gzip wrapper still dominates on tiny payloads, which is why Deflate (no header) and Brotli (stronger core) both beat Gzip on the same 250 bytes. The lesson: for short payloads don't assume Gzip wins; Deflate or Brotli are often better, and Gzip only pulls clearly ahead once the text is long and redundant.

Table 5: Base64 / Hex inflation, and the net effect of "Base64 then compress"

Compressed output is binary and must be encoded to live in text. For the 188 bytes from Gzip on the default input, the two text encodings give:

EncodingLengthInflation vs compressed
Binary (raw)188 bytes1.00×
Base64252 chars1.33×
Hex376 chars2.00×

Base64 inflates to 4/3 and Hex to 2× — the inherent cost of encoding. A common myth is that "Base64 first, then compress" gets smaller; the measurement says otherwise. Again with the default input (250 bytes):

StepSizeNote
Original250 bytesstart
Base64 first336 bytesinflated +34.4%
then Gzip276 bytesrecovers only part of the inflation
Gzip original directly188 bytesbaseline

Note: "Base64 then Gzip" yields 276 bytes, which is 88 bytes more than "Gzip directly" (188 bytes), for a net saving of -10.4%. Base64's 33% inflation cannot be fully undone by later compression, so always compress first and Base64 second, never the reverse.

Table 6: HTTP transport savings via Content-Encoding (RFC 9110)

Over the network, compression is declared with the Content-Encoding response header and negotiated by the client with Accept-Encoding, per the HTTP Semantics standard RFC 9110 (published 2022, replacing RFC 7231). This tool reproduces exactly those encodings so you can verify server output offline:

Content-Encoding tokenAlgorithmStandardStatus
gzipGzipRFC 1952broadest server support, best compatibility
deflateDeflateRFC 1951historically often implemented as zlib wrapper, so used alone less
brBrotliRFC 7932preferred for static assets (CSS/JS/fonts/HTML), smaller at same size
zstdZstandardRFC 8878newer algorithm, adopted by some CDNs (not implemented here, shown for context)
identityno compressionRFC 9110default / placeholder, means no encoding
compressUNIX compress (LZW)historicobsolete, rarely used

Worth mentioning: Zstandard (Zstd, RFC 8878, released by Facebook in 2015) sits between Gzip and Brotli on the ratio/speed curve and decodes extremely fast, and is being picked up by more CDNs; it is outside this tool's four modes, included above only for algorithm-family context. Major CDNs (Cloudflare, Akamai, Fastly) enable exactly Gzip and Brotli (br) by default, consistent with the RFC 9110 negotiation model.

Three real examples (consistent with the page defaults)

All three examples use this tool's default demo text (250 bytes) and default encoding (Base64), only switching algorithm or order, and the numbers match the tables above.

Example 1: short text with Gzip

Default text (250 bytes) kept at Gzip + Base64 and run: Gzip gives 188 bytes (saved 24.8%) → 252 chars in Base64. Shows that even a short English sample already compresses positively with Gzip, but the 18-byte wrapper is still a meaningful tax on tiny payloads.

Example 2: same short text, Brotli still wins

The same 250-byte default text, switched to Brotli (page default level 6): 167 bytes (saved 33.2%) → 224 chars in Base64. On the same short text, Brotli's context modeling beats Gzip by 21 bytes.

Example 3: net effect of Base64-then-compress

Default text 250 bytes → Base64 first = 336 bytes (+34.4%) → Gzip = 276 bytes; direct Gzip of the original is only 188 bytes. Base64-then-Gzip (276 bytes) is 88 bytes more than direct compression (188 bytes), net saving -10.4%. Conclusion: when text transport is required, always compress first, then Base64, never the other way around.

More questions

Why does Gzip on a very short text sometimes come out longer than the original?

Because Gzip always writes a 10-byte header plus an 8-byte CRC/length trailer, 18 bytes in total. If the original is tiny and low on redundancy, that 18-byte cost exceeds what gets squeezed out, so the result grows. This tool's default input box (250 bytes) still nets a positive 24.8% with Gzip, but switch to the no-header Deflate or stronger Brotli and the gain is larger.

Zlib and Gzip share the Deflate core, so why are their volumes different?

The body compression is identical; only the wrapper differs. Zlib adds a 2-byte header plus 4-byte Adler-32 (6 bytes total) on top of Deflate; Gzip adds a 10-byte header plus 8-byte trailer (18 bytes total). Measured on the same input by this tool: Zlib is 6 bytes larger than raw Deflate and Gzip is 18 bytes larger, matching the RFCs. So for the same body, Gzip is always exactly 12 bytes larger than Zlib.

Is it worth compressing data that is already Base64-encoded? What is the net effect?

Rarely, and it often backfires. Base64 first inflates volume by about 33% (3 bytes become 4), and later Gzip recovers only a fraction. With this tool's default text: 250 bytes → 336 Base64 → 276 Gzip, which is actually 88 bytes more than Gzip-on-original (188 bytes). The correct order is compress, then Base64.

For web transport, should Content-Encoding be gzip or br?

Prefer Brotli (br) for static assets (CSS/JS/fonts/HTML): at the same size it is usually smaller than Gzip and decodes fast. Fall back to Gzip for dynamic responses or to support older clients. Both rely on the client advertising support via Accept-Encoding and are negotiated by the server per RFC 9110 (see Table 6). This tool lets you verify both encodings' output offline without capturing packets in production.