Base64 and gzip compression

Published

Base64 turns every 3 bytes into 4 characters, so the encoded data is 33% larger. But each Base64 character carries only 6 bits of information in an 8-bit byte. Compression algorithms such as gzip (DEFLATE) and Brotli use Huffman coding, which spends fewer bits on frequent symbols, and they win back most of that waste.

What happens in practice

We measured it with Node.js zlib (gzip level 9 and Brotli defaults). The “already compressed” rows use random bytes, which behave like PNG, JPEG or MP3 data:

Data Raw Base64 gzip(raw) gzip(Base64) Brotli(Base64)
Compressed file, 1 KB 1,024 B 1,368 B 1,047 B 1,073 B 1,054 B
Compressed file, 100 KB 102,400 B 136,536 B 102,453 B 102,875 B 102,685 B
English-like text, 10 KB 10,240 B 13,656 B 1,920 B 2,663 B 2,226 B

Rule of thumb: for already-compressed formats, Base64 + gzip is within about 1–5% of the original size, because the Huffman stage removes the 6-of-8-bits redundancy. For compressible originals such as text, JSON or BMP, compressing the raw data is clearly better: in our test, gzip of the Base64 text was 39% larger than gzip of the text itself.

Why it is not exactly zero

DEFLATE finds repeated sequences byte by byte. Base64 splits input bytes across character boundaries, so a repetition in the original appears in the encoded text only when it is aligned to the same 3-byte offset. Compression therefore finds fewer matches in Base64 than in the original binary.

Takeaways

  • Always enable gzip or Brotli on HTML, CSS, JS and JSON that contain Base64. Check yours with the gzip test.
  • Compress first, then encode, when you control both ends (for example gzip | base64 in scripts).
  • Never inline large resources just because “gzip fixes it”: inlined data still has to be downloaded and parsed before rendering.

Comments (0)

Questions, ideas or a bug in “Base64 and gzip compression”? Leave a comment, rate the tool, or reply to others.

No comments yet. Be the first to share your feedback!

Leave a comment

Rate this tool:
Esc
↑ ↓ move↵ openEsc close