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.
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.
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.
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:
- Corpus: the Canterbury corpus — 11 files, 2,810,784 bytes — from
corpus.canterbury.ac.nz/resources/cantrbry.zip(SHA-256c44b686d…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.