Changelog

Updated 18 August 2026

A dated record of what changed, what was measured, and what was not. Entries are written on the day the work lands. Nothing here is backdated, and a measurement that was not taken is written down as a measurement that was not taken.

18 August 2026 — the benchmark tables, published in full

The 15 August entry summarised a benchmark most readers had no way to inspect. That benchmark is now a page: How UnboundPDF handles large PDFs locally carries the tables themselves — every operation on a 300-page scan and on a 1,000-page document across three browser engines, the compression ratios per engine, the OCR timings, the observed completions per operation class with their memory readings, the difficult-document behaviours, and the two hand-run phone tables verbatim. It also carries, in the same page rather than in a footnote, the five requirements the benchmark did not pass and the nine things nobody measured.

The PDF Privacy Lab gained three sections on local execution, large-file reliability and output verification, in which every claim is tagged as measured, architecture, limitation or untested — because “we built it this way” and “we measured it” are different statements and a privacy page is the wrong place to blur them. It also now publishes the offline suite’s privacy result: every cache entry on the origin is byte-scanned for the input documents, and no byte of either appears in any of them.

No product code changed in this entry. Two pages were written and one was extended; nothing was measured that was not already measured on 15 August, and no figure moved.

15 August 2026 — large-document runtime, and the benchmark behind it

What changed in the product

The tools now share one execution runtime for long jobs. In practice that means five things you can see. Long documents are worked through in stages rather than all at once. Pages are rendered as you reach them, and page thumbnails stop at 200 however long the document is. Each job is checked against your device before it starts, and what that check found is shown to you rather than kept back. Progress is a phase and a counter — “Recognizing page 2 of 3” — never an invented percentage. And every long run has a Stop button that leaves your original file untouched and the tool ready to run again.

Seven tools additionally have a low-memory mode: the PDF editor, Fill & Sign and Sign PDF evict cached pages and clamp how much canvas is drawn at once; Split, Organize and Rotate narrow the thumbnail band; PDF to JPG narrows that band and also exports in smaller batches.

The per-tool capability record is now public and machine-readable at /capabilities.json. It states, per tool, the engine used, whether a first-party worker is involved (none is), whether WebAssembly is involved, what offline support has actually been proven, whether low-memory mode applies, how cancellation behaves, the benchmark behind it, and the known limitations. The build refuses to publish it if any field contradicts the code that ships.

What was measured

On 15 August 2026, on one desktop machine (Apple M4, 16 GB, macOS 26.3.1), driving the real user interface in Chromium, Firefox and WebKit — the engine behind Safari — across a 12-document corpus:

  • 124 runs, 124 completed or refused cleanly. No crash, no silent hang, no “something went wrong”. No run modified its input file.
  • 79 of 79 byte-producing runs were reopened and checked in poppler, a PDF stack with no code in common with ours: page counts correct, page one rasterised, ZIP entry counts equal to page counts, OCR output carrying 91,127 searchable characters, a Chinese document keeping 2,988 characters through a re-save. The other 45 runs produce no output document.
  • Documents observed completing (the largest we watched each operation finish, not the point where it stops): compression and merging on a 300-page, 119 MB scan and a 500-page, 99.6 MB mixed document; a 1,000-page document opened, merged, compressed and exported as 1,000 images; a 756-page specification with a deep bookmark tree opened and compressed with all pages intact. First page painted, and first thumbnail drawn, in roughly half a second at every size on every engine.
  • Encrypted and damaged documents are answered, not spun on. Nine encrypted-file runs refused in under 0.6 seconds with a named reason and a next step. A file with a truncated cross-reference table — which poppler will not open at all — was repaired and processed on all three engines, recovering 22 pages.
  • Compression depends on your browser, not only on your document. Identical input, identical Balanced setting: the same 119 MB scan came out at 34% of its original size in Chromium, 39% in Firefox and 57% in WebKit. That path re-encodes oversized photographs with the browser’s own JPEG encoder, and the three encoders disagree. We will not publish a single “compress by X%” figure, because there is not one.
  • OCR depends on your browser too. Recognising a 100-page scan took 94 seconds in Chromium and 89 in WebKit, and 19.7 minutes in Firefox — roughly twelve times longer, for byte-for-byte the same recognised text. Firefox is slow at this, not stuck: progress kept counting and Stop stayed live throughout.

What was not measured, and what we therefore do not claim

  • No heavy work runs off the main thread in our own code. The registry records no first-party worker on any of the 43 tools, and the build refuses any row that claims one. One was built and benchmarked; it made nothing faster and used considerably more memory, so it is off. We do not describe this product as using background workers.
  • Low-memory mode exists; we cannot tell you it reduces risk. “Reduces the risk of failure” is a comparison against a failure rate, and the measured failure rate is zero — no run has ever failed on any device we can instrument. We can name the mode and say what it does. We cannot claim an effect nothing has measured.
  • No allocation failure has ever been produced. In 144 instrumented runs across two rounds, nothing ran out of memory. The pre-flight check that is supposed to catch an unsafe job before it starts therefore has thresholds that no real failure has ever calibrated, and we have never observed how a genuine out-of-memory failure behaves in this product.
  • Peak memory does not reproduce, so no memory number here is a bound. One cell re-run five times under identical conditions spread 13%; another spread 82%, with byte-identical output both times. Every memory figure we hold is one sample of a noisy quantity, and we publish none of them as a ceiling or a guarantee.
  • “The page stays usable while it works” was measured on desktop only. Responsiveness during processing was probed on one desktop machine, on three kinds of operation, and the first version of the instrument had to be discarded because it invalidated its own result. No mobile responsiveness measurement exists at all. Progress and the Stop button are real everywhere; the evidence that the rest of the page still answers you while a job runs is desktop evidence.
  • The tools do not verify their own output. The four guided /make/ chains check the produced bytes before showing you a receipt. The 33 individual tool pages do not: their outputs were verified afterwards, externally, by us, in poppler. That is verification of the product, not verification by the product, and the distinction matters if you are relying on it.
  • The matrix is a sample, not a sweep. 68 planned cells were pruned to fit the time budget, each with a recorded rule and reason, and OCR at 300 pages was run only in Chromium — never in Firefox or Safari’s engine, which is the pairing where OCR differs most.
  • Whole device classes are untested. Nothing has been measured on a mid-range laptop — the class most likely to struggle — on Windows, on Linux, in Edge, in iOS Safari’s desktop-class mode, or with several tabs working at once, which is how people actually run out of memory.
  • No memory measurement exists for any phone. The only phone results are two hand-run checks on 13 August 2026, on older builds: an iPhone 14 in Safari completed Balanced compression of a 119 MB, 300-page scan in 30–40 seconds, and one Xiaomi handset in Chrome completed the same job in 60–100 seconds. Neither run was instrumented, the Xiaomi’s model was not recorded, and neither is a promise about your handset.
  • One rough edge we found and did not fix. Exporting a 1,000-page document to images is expensive out of proportion to the file: a 2.3 MB input produced a 320 MB archive and the highest memory reading in the matrix, because every page image is held before the archive is assembled. It completed on all three engines and the output verified; it is a page-count cost, not a file-size cost, and it is unfixed.

What changed on the site

Every public statement about size, memory, device capability and speed was re-audited — 48 tracked statements across 108 pages — and rewritten against the benchmark. Five pages had described the same constraint five different ways; two tool pages said there was no limit while four guides said memory was a hard ceiling; and two mobile guides carried an untested promise about how a run behaves when a device runs short of memory — nothing has ever produced that failure here, so nothing could have tested it. Those now read the same way everywhere: no fixed cap is claimed, sizes are given as documents an operation was observed finishing on a dated benchmark, browser-dependent results name the browser, and where a thing was not measured the page says so.

What a run needs still depends on the operation, the document’s structure, the browser and the resources your device has free. UnboundPDF checks those before processing and tells you what it found, rather than hiding it or letting the tab fail without explanation.