Data & Compression

What Is Lossless Data Compression?

By Lucian — builder & engineer, LK Forge

Lossless compression makes a file smaller and then gives every original byte back — decompress it and you have an exact copy, not an approximation. That is the whole promise, and it is testable: compress, decompress, and check the result matches the source bit-for-bit. We ran that test on a standard set of files with five real compressors, and measured how small each one goes. Below is what lossless actually means, a live demo you can run on your own text, and the numbers.

5.7×
smallest — brotli on the corpus (17.5% of the original)
0 bytes
lost across all 55 round-trips — every byte restored
3.85×
gzip, the 1990s baseline — modern codecs pack ~49% tighter
45% → 17%
how far real codecs beat the naive per-byte entropy floor

Try it: lossless in your browser

Type or paste anything below. Your browser compresses it with gzip (the DEFLATE algorithm, via the built-in CompressionStream API), then immediately decompresses it and checks the result against what you typed. Nothing leaves your device. Watch the size shrink on repetitive text — and notice the output always comes back identical.

original bytes
gzip bytes
ratio
Waiting for input…

How small can lossless go?

There is a naive limit called the order-0 entropy — the best you can do if you only look at how often each byte appears, ignoring order. For this corpus that floor is 45% of the original. Real compressors blow straight through it by modeling context and repetition: gzip reaches 26%, and modern codecs (xz, brotli) reach about 17.5%. Bigger bar = smaller file.

Order-0 entropy floor 2.21× · 45% gzip -9 3.85× · 26% bzip2 -9 5.18× · 19% zstd -19 5.45× · 18% xz -9e 5.70× · 18% brotli -q11 5.73× · 17% lkforge.com

Whole-corpus ratio (original size ÷ compressed size); the % is the compressed size as a share of the original. The order-0 entropy floor is the per-byte limit; every real codec beats it by exploiting patterns across bytes.

Compressibility depends on the data

The same codec behaves completely differently on different files. The standout is kennedy.xls: a spreadsheet full of structure and repeated zeros, it drops to just 5% of its size with xz. A fax image (ptt5) compresses almost as hard. English prose sits around 30%, and the already-dense SPARC binary (sum) resists the most. Each row is one file; every number below survived a byte-for-byte round-trip check.

File Type Size gzip bzip2 xz zstd brotli
alice29.txt English text 149 KB 36% 28% 32% 32% 31%
asyoulik.txt English text 122 KB 39% 32% 36% 36% 34%
cp.html HTML 24 KB 32% 31% 31% 31% 28%
fields.c C source 11 KB 28% 27% 27% 27% 24%
grammar.lsp Lisp source 4 KB 33% 34% 35% 33% 30%
kennedy.xls Spreadsheet 1006 KB 20% 13% 5% 6% 6%
lcet10.txt Technical text 417 KB 34% 25% 28% 28% 27%
plrabn12.txt Poetry 471 KB 40% 30% 34% 35% 34%
ptt5 Fax image 501 KB 10% 10% 8% 9% 8%
sum SPARC binary 37 KB 33% 34% 25% 29% 27%
xargs.1 Man page 4 KB 41% 42% 43% 41% 35%

Each cell is the compressed size as a percent of the original (smaller is better). Already-compressed data — a JPEG, an MP3, a ZIP — has little redundancy left, so lossless tools barely shrink it; that is expected, not a failure.

When to use lossless vs lossy

Use lossless whenever every byte matters: text, source code, spreadsheets, logs, executables, and archives — anything where a changed bit is a bug. Use lossy when the data is headed for human eyes or ears and a small, well-chosen loss is invisible: photos, music, streaming video. The reason lossy wins so much more size is exactly that it is allowed to discard information — see how that trade plays out for photos in image compression: quality vs file size, and for documents in how PDF compression works.

Want to try it on real files? Our Image Compressor and PDF Compressor run entirely in your browser — nothing is uploaded.

Reproduce this

No cherry-picking — every figure is the whole-corpus total on a standard public file set, using each tool's stock maximum setting. Run it yourself:

Method
  • Corpus: the Canterbury corpus — 11 files, 2,810,784 bytes — from corpus.canterbury.ac.nz/resources/cantrbry.zip (SHA-256 c44b686d…39a1a6).
  • Settings: gzip -9, bzip2 -9, xz -9e, zstd -19, brotli -q11 — each at maximum.
  • Ratio: total original bytes ÷ total compressed bytes, summed over all 11 files.
  • Lossless check: each stream was decompressed and compared to the original by SHA-256 — all matched.
# one file, every codec, at max — sizes in bytes
for f in corpus/*; do
  o=$(wc -c < "$f")
  g=$(gzip  -9  -c "$f" | wc -c)
  b=$(bzip2 -9  -c "$f" | wc -c)
  x=$(xz    -9e -c "$f" | wc -c)
  z=$(zstd  -19 -c "$f" | wc -c)
  r=$(brotli -q 11 -c "$f" | wc -c)
  echo "$f  orig=$o gz=$g bz=$b xz=$x zstd=$z br=$r"
done

Exact bytes depend on tool versions (here: gzip 1.14, bzip2 1.0.8, xz 5.8.3, zstd 1.5.7, brotli 1.2.0) — the ordering and the ~5.7× ceiling generalize. The order-0 entropy floor is -∑ p·log₂p over byte frequencies.