What was tested and what wasn't?
The test used the same, unmodified compression code that this website's PDF compressor uses. For the measurement, however, it did not run in the browser. Instead, it was called directly in Node.js. This makes it possible to record the input, the settings and the saved result precisely for every run.
- Compression module: QPDF 12.2.0 as WebAssembly, wrapper version 0.3.0. The wrapper's build script pins QPDF 12.2.0, and the installed module also reports 12.2.0 when queried.
- Environment: Node.js 24.18.1 on Windows 11, build 26200, x64.
- Scope: three synthetic input files, nine compression runs and one test file with a signature placeholder that is supposed to be rejected.
- Verification: twelve saved PDFs with 24 pages in total, each with a structure check and a rendered page view.
The following are not part of this measurement:
- processing time; no time was measured,
- behavior in individual browsers or on real smartphones and tablets,
- real photos, scans, large files or documents from users,
- other compression programs or online services,
- an average saving that you could expect for your file.
Test files, settings and downloads
The test uses only self-generated PDFs. It includes no customer documents, no real-world photos and no signatures of real people. The image in the image file is also generated. It shows a texture with a color gradient and is neither a photo nor a scan.
- Text file, 3,029 bytes: two pages with text, a filled-in form field, a link, a page rotation and a tag in the structure tree.
- Image file, 1,359,079 bytes: the same components, plus a generated image of 640 × 800 pixels. The text file without the image is only 3,029 bytes, so most of this file size comes from the image.
- Already optimized text file, 2,721 bytes: it serves as the case where nothing more can be gained.
- File with signature placeholder, 3,139 bytes: it contains only the structure of a signature, not a real digital signature. It is used to check whether the compressor rejects signed files.
Same starting point for every run
- Every run starts with the unmodified original bytes. If a run needs several attempts, each further attempt also starts again from the original and not from the previous result.
- All results contain both complete pages. No pages were removed, nothing was packed as a ZIP, no images were downsampled to fewer pixels and no entire pages were converted to images. This is the only way the byte counts of the modes can be compared with one another.
- Each result was saved under its own file name. Byte count and SHA-256 checksum are recorded for input and output. The checksum is a fingerprint of the file: if even a single byte changes, the checksum changes.
- For each run, the log records the mode, the target size where applicable and the JPEG quality actually used.
What the three modes do technically
In the log and in the tables, the modes are called lossless, balanced and small. In the tool, you will find them under these names: lossless is Lossless optimization, balanced is Balanced and small is Smaller file. Lossless optimization only optimizes the structure of the file, meaning objects and compressed data streams. Balanced additionally re-encodes suitable images as JPEG at quality level 80. If a target size is missed, it follows with an attempt at 70. Smaller file starts at level 65 and, if the target is missed, drops to 50 and then to 40. If you have specified a target size and the original or the structurally optimized version already meets that target, no lossy JPEG attempt is needed. At the end, the tool uses the smallest checked version. If no version is smaller than the original, the original is kept. A particular saving is therefore not guaranteed.
According to the QPDF 12.2 documentation, QPDF does not reduce image resolution in this process. However, JPEG re-encoding can create visible artifacts, and QPDF only uses re-encoded image data if it is smaller. The guide Compressing PDFs without quality loss explains what this means for image quality.
Files and checksums for verification
The following table links all test files and result files. After downloading, compare the SHA-256 checksum using a checksum tool of your choice. If it matches, you have exactly the measured file. The English-language log reproducibility-manifest.json contains the exact calls and settings of all runs.
Results: file size presented honestly
Test runs from 13 October 2026 in a chart
The chart shows all nine runs of our measurement with QPDF 12.2.0 (WASM) in Node.js on Windows 11. Filter by test file or method and switch between exact byte counts and remaining size as a percentage.
9 of 9 runs shown
Text · Lossless
reduced
- Original
- 3,029 bytes · 100 %
- Result
- 2,721 bytes · 89.83 %
- Specified limit
- No limit specified
Image · Lossless
reduced
- Original
- 1,359,079 bytes · 100 %
- Result
- 1,358,764 bytes · 99.98 %
- Specified limit
- No limit specified
Image · Balanced
reduced
- Original
- 1,359,079 bytes · 100 %
- Result
- 179,708 bytes · 13.22 %
- Specified limit
- No limit specified
Image · balanced, repeat run
same size, different checksum
- Original
- 1,359,079 bytes · 100 %
- Result
- 179,708 bytes · 13.22 %
- Specified limit
- No limit specified
Image · Strong
reduced
- Original
- 1,359,079 bytes · 100 %
- Result
- 125,710 bytes · 9.25 %
- Specified limit
- No limit specified
Image · Strong
Target reached
- Original
- 1,359,079 bytes · 100 %
- Result
- 125,710 bytes · 9.25 %
- Specified limit
- 250,000 bytes
Image · Strong
Target not reached, complete PDF delivered
- Original
- 1,359,079 bytes · 100 %
- Result
- 74,707 bytes · 5.5 %
- Specified limit
- 128 bytes
Image · Strong
Target already met beforehand
- Original
- 1,359,079 bytes · 100 %
- Result
- 1,358,764 bytes · 99.98 %
- Specified limit
- 1,359,079 bytes
Already optimized text · Lossless
Original kept unchanged
- Original
- 2,721 bytes · 100 %
- Result
- 2,721 bytes · 100 %
- Specified limit
- No limit specified
Unchanged – original kept
Historical measurement: it says nothing about browsers, phones, the current version or other tools. Percentages show the remaining size, not the savings. An entered limit is a numerical target, not a promise. Regardless of the filters, the table below contains all nine runs.
This test cannot predict how much your own PDF will shrink. That depends on what your file contains. The three test files alone show the range. In lossless mode, the small text file became 10.17 percent smaller, while the image file became only 0.02 percent smaller in the same mode. Only JPEG re-encoding brought a saving of 86.78 percent for the image file. The table contains all nine runs, including those without a noticeable saving.
The saving is always calculated from the actual bytes: bytes saved divided by the original size. For the balanced run, that is 1,179,371 of 1,359,079 bytes, or 86.78 percent. You can recalculate this for your own file with the compression ratio calculator.
JPEG quality is not a percentage saving
The values 80, 65 and 40 are settings of the JPEG encoder. They are not percentages for the reduction. In this test, quality level 80 saved 86.78 percent, while level 65 saved 90.75 percent. With a different file, the same levels can produce very different results.
Why the no-saving case is included
A test that only shows the best saving leaves out an important case: what happens when nothing more can be gained? For the already optimized text file of 2,721 bytes, lossless mode did not produce a smaller version. The compressor therefore kept the original. The output was 2,721 bytes, the saving was 0 bytes, and input and output have the same SHA-256 checksum. This demonstrates with the real compression module that, in this case, you do not receive a rewritten file that brings no benefit. The guide PDF won't get smaller explains what you can do in that situation.
Target size met, missed or already satisfied
- Target 250,000 bytes: the very first attempt at level 65 came to 125,710 bytes. The target was therefore met, and the result is even byte-identical to the run without a target.
- Target 128 bytes: for two pages with an image, this is unrealistically small. Even the last level, 40, only got down to 74,707 bytes. The compressor reports that the target was not met and still delivers a file. For this test file, the saved 74,707-byte result file contains both pages, and it passed the feature checks described further below. The image data was lossily re-encoded in the process. This run does not prove that all content is preserved for every other file.
- Target 1,359,079 bytes, exactly the original size: the target was considered already met. Only the structural, lossless optimization ran. It produced 1,358,764 bytes, the same size as the lossless run. The image was not re-encoded as JPEG, because the logged calls contain no JPEG setting.
Same size, different checksum
The repeat of the balanced run again produced exactly 179,708 bytes, but a different SHA-256 checksum. The run with the already met target also has the same size as the lossless run, yet it has its own checksum. One possible reason is that writing a PDF can, for example, generate a new document ID. By contrast, the small runs without a target and with a target of 250,000 bytes matched down to the byte. A checksum therefore identifies one specific saved file. If you repeat a run, including in the browser, you will not necessarily get a byte-identical file, even if the size stays the same.
Rendering and features checked separately
A smaller file does not show whether text, form and link were preserved. A good preview does not prove this either. For this reason, the saved files were checked with two independent libraries. pdf-lib reads the saved internal structure, and PDF.js 6.4.299 renders the pages and reads text and annotations. For this purpose, PDF.js ran in an isolated Chromium instance, version 151.0.7922.34. This check of the finished files is separate from the compression, which was measured in Node.js on Windows 11. Compression in the browser or on mobile devices was not measured, and the check says nothing about how other PDF programs behave. Each check has its own method and applies only to these test files.
One detail about the form field: its value does not reliably appear in the normal text extraction of PDF.js, so it was read from the annotations. If you search for an entered form value in a compressed PDF and cannot find it, this does not automatically mean that the value is missing.
With balanced and small, the image was lossily re-encoded as JPEG, except in the small run whose target was already met beforehand. The decoded content instructions for text and lines stayed the same, but the texture's image data did not. On the rendered pages of the results from the image file, the position and extent of the image and the page rotation remained as in the original. If you look at the files yourself, note that the generated image already lies over several lines of text in the original. This overlap is part of the test file and is not damage caused by compression. It remains in the results. No statement about the legibility of every line and no quality rating follows from this. A generated image with texture and color gradient also says little about how photos, scans or small print in scans respond to the same level. The guide Reducing the size of scanned PDFs covers this topic.
The signature placeholder only shows that the compressor recognizes a file with a signature structure and does not process it. According to the compression code, encrypted and certified files are also rejected. This test does not check whether a real signature is valid, and it does not bypass any protection. You can read more about this in the guide Compressing PDFs with signatures and forms.
Limits and checking it yourself
Is the tool better than PDF24 or Adobe?
This page does not answer that question. We did not run any other programs or online services with the same files. A comparative verdict on quality, speed or price would therefore not be supported by evidence. Leaderboards with percentages or sliders do not replace such a comparison either. A fair comparison needs the same complete input file, the same pages, recorded settings, exact byte counts and the same feature checks for all results.
How to check your own PDF
- Keep an unmodified copy of your original.
- Open the PDF compressor and select the file. If image detail matters, start with the lossless mode.
- Write down the exact size in bytes of the original and of the result, for example from the file properties, and calculate the saving with the compression ratio calculator.
- Start each further attempt from the original again, not from a result that has already been compressed. Save each result under a new file name so that you don't overwrite anything.
- Open the saved file in the program that the recipient also uses. Check all pages, search for a known word, check form values and links, and look at images and small print at actual size.
- If your PDF is digitally signed, encrypted or certified, do not compress it with this tool. Instead, clarify the process with the issuer.