Why the size number is the wrong number
Ask any compressor how it did and it answers in megabytes. That is the easy half of the question, and on its own it is close to meaningless: a tool that deleted every page but the first would post a spectacular number.
The half nobody reports is what the file gave up to get there. A PDF can be made dramatically smaller by rendering each page to a JPEG and throwing away everything underneath — the text, the links, the form fields, the bookmarks, the accessibility tags. The result looks identical on screen and is a different kind of object. You cannot search it, copy from it, fill it in, or hand it to a screen reader.
That transformation is not exotic. It is what "maximum compression" means in a lot of tools, including, until recently, the two loudest options in ours.
What was measured
Four things per file per tool, because the first one alone can be gamed:
- Size. Bytes out against bytes in.
- Pages. A compressor that drops a page has not compressed anything.
- Text. Every character the original could hand back, can the result still hand back. This is measured by extracting the text from both with the same parser and comparing, not by looking at the pages.
- Opens. Does the result parse as a PDF at all.
The text check is the one that separates these tools, and it is invisible to anything that only weighs the file.
Why these four
Ghostscript and qpdf, because they are what the answers point at. Search for how to compress a PDF and you land on gs -dPDFSETTINGS=/ebook within about two results, and a good number of the web tools that will do it for you are running one of these two behind the upload form.
They are also tools that can be run again. A hosted service can change what it does between one Tuesday and the next without telling anybody, which makes a measurement of it true on the day and unreliable afterwards. A version-pinned command is reproducible, so the numbers in this report can be checked rather than believed.
We are in the table, and we are not top of it.
What each tool returned
A scanned document · 5.83 MB
Two pages of photographed paper. The common case for a file somebody actually needs to shrink.
| Tool | Out | Change | Pages | Text |
|---|---|---|---|---|
| Lyonite — recompress images | 0.62 MB | 89% smaller | all kept | kept |
| Ghostscript /screen | 0.30 MB | 95% smaller | all kept | kept |
| Ghostscript /ebook | 0.77 MB | 87% smaller | all kept | kept |
| qpdf --optimize-images | 3.04 MB | 48% smaller | all kept | kept |
A mixed text-and-image document · 7.46 MB
Eight pages of a government study guide: body text, headings, and around fifty photographs.
| Tool | Out | Change | Pages | Text |
|---|---|---|---|---|
| Ghostscript /screen | 0.44 MB | 94% smaller | all kept | kept |
| Ghostscript /ebook | 0.83 MB | 89% smaller | all kept | kept |
| Lyonite — recompress images | 3.28 MB | 56% smaller | all kept | kept |
| qpdf --optimize-images | 6.96 MB | 7% smaller | all kept | kept |
One page, one photograph · 0.10 MB
The metadata corpus file: a single page carrying a geotagged photo, an attachment and a script.
| Tool | Out | Change | Pages | Text |
|---|---|---|---|---|
| Ghostscript /screen | 0.02 MB | 85% smaller | all kept | kept |
| Lyonite — recompress images | 0.03 MB | 71% smaller | all kept | kept |
| Ghostscript /ebook | 0.05 MB | 56% smaller | all kept | kept |
| qpdf --optimize-images | 0.10 MB | 1% smaller | all kept | kept |
A small text-only PDF · 2.1 KB
Two kilobytes. Nothing to compress — the question is whether a tool knows to leave it alone.
| Tool | Out | Change | Pages | Text |
|---|---|---|---|---|
| Lyonite — recompress images | 2.1 KB | unchanged | all kept | kept |
| qpdf --optimize-images | 2.2 KB | +3% bigger | all kept | kept |
| Ghostscript /ebook | 5.1 KB | +141% bigger | all kept | kept |
| Ghostscript /screen | 5.1 KB | +143% bigger | all kept | kept |
Rows are ordered by how much each tool saved, best first — which is why we are third on one of them.
Reading the table
Ghostscript's /screen preset wins on size in every single row, and it should — it is the aggressive setting, and it is doing more than we do. It resamples, it recompresses the content streams, it rebuilds and subsets the fonts. We only touch the pictures.
The row worth sitting with is the mixed text-and-image document, where /ebook returned 89% and we returned 56% on the same file with the same text intact. That is not a rounding difference. Most of it is font and content-stream work we do not attempt, and some of it is that Ghostscript is willing to resample more aggressively than we are at the same nominal target.
Where we come out ahead is narrower and more specific. On the scan — a document that is essentially photographs of paper, which is the common case for a file somebody actually needs to shrink — we returned 89% against /ebook's 87%. And on a small text-only PDF we returned the file unchanged, where both Ghostscript presets handed back something more than twice the size they were given.
The tool that made the file bigger
A compressor that makes a file bigger has failed, and it is a failure that goes unnoticed because nobody checks a small file afterwards.
Ghostscript does this because it is not really a compressor. It is a PDF interpreter that rewrites the document through its own writer, and that writer has a floor: fonts get re-embedded, structures get rebuilt, and on a two-kilobyte document the rebuilt version costs more than the original did. The preset name says compression; the mechanism says conversion.
We hit this too, in a different place, and it is why the tool now checks every image individually and keeps the original bytes whenever a re-encode would be larger. One awkward picture cannot make the whole document worse. The same guard runs on the finished file: if the output is not smaller than the input, you get the input back.
What we do not do yet
Being honest about the 56% means being specific about what is missing.
- Fonts. We do not subset or deduplicate embedded fonts. On a text-heavy document with several full font programs embedded, that is real weight we walk past.
- Content streams. We do not recompress page content streams, which on some documents is a few percent and on badly-written ones is more.
- Duplicate images. A document that embeds the same logo forty times gets forty copies compressed forty times, rather than one copy referenced forty times.
- Colour spaces. Indexed, CMYK and ICC-based images are left alone rather than converted, because getting a colour transform subtly wrong produces a file that opens with the colours changed — worse than one that is merely larger than it could be.
Those are the next four things, roughly in that order.
Running this yourself
Everything in the table came from two scripts in the open repository, run against a folder of PDFs.
The comparison script runs each tool over each file and reports all four measurements. Ghostscript and qpdf run as commands; ours runs through the actual page in a real browser, driven end to end and captured from the download, so what is measured is what a person would get rather than an internal function nobody can reach.
Point it at your own documents. The interesting cases are rarely the ones a test corpus thinks of.
# every tool, every file, all four measurements node scripts/compare-compressors.mjs ~/your-pdfs # just ours, as a regression check node scripts/compress-verify.mjs ~/your-pdfs
Limits
This is four files and four tools, which is enough to show a pattern and not enough to rank anything definitively. The files are one scan, one mixed text-and-image document, one small text-only PDF and one synthetic corpus file — a reasonable spread, not a representative sample of everything people compress.
Nothing here tests visual quality. Every tool in this table degrades images to save bytes, and whether the result still looks acceptable is a judgement no script makes. Read the numbers as "what survived structurally", not as "what still looks good".
Adobe Acrobat is not in the table. We have not run it, so we are not going to guess at it, in either direction.
If a number here is wrong, or you can reproduce something different, tell us and we will re-run it and say so on the page. Corrections get dated, and the original figure stays visible.
Check this yourself. If I got it wrong, tell me.
Every number here came from files you can download and a checker you can run, so you do not have to take my word for any of it — clone the corpus and get your own result.
If it disagrees with mine, or if you build one of the tools named here and I measured it unfairly, out of date, or with a setting you would not have used, send it to hello@lyonite.com.
I reply within 48 hours. If you are right, the page is corrected with the date on it and your correction credited, and the old number stays visible so the change is legible. If a tool has since been fixed, that is the update I most want to publish. Nothing here is worth defending past the point it stops being true.