Conversion Lab
Measured, not promised.
These are timing and output-size measurements for the exact converter code FileMorf ships to your browser, run against a fully synthetic, seeded PDF corpus. Raw results and the corpus manifest are downloadable below.
Last measured July 28, 2026 · build 4ef6888
What this is
FileMorf's PDF tools — merge, split, extract, page numbers, watermark — run locally in your browser using the open-source pdf-lib engine, and batch downloads are packaged with JSZip. The Lab benchmarks call those exact shipped functions (not a reimplementation) so the numbers describe the real code paths, and the corpus is generated from a fixed seed so anyone can reproduce the input files byte-for-byte.
Merging
| Benchmark | Input | Median | p95 | Output |
|---|---|---|---|---|
Merge 2 PDFs mergePdfs() over 2 three-page documents. | 2 PDFs × 3 pages | 2.4ms | 5.7ms | 9.95 KB |
Merge 10 PDFs mergePdfs() over 10 three-page documents. | 10 PDFs × 3 pages | 6.3ms | 9.1ms | 45.94 KB |
Merge 50 PDFs mergePdfs() over 50 three-page documents. | 50 PDFs × 3 pages | 30.4ms | 32.7ms | 226.95 KB |
Splitting & extraction
| Benchmark | Input | Median | p95 | Output |
|---|---|---|---|---|
Split a 20-page PDF into single pages splitPdf() with no range — one output document per page. | 1 PDF × 20 pages | 5.9ms | 8.1ms | 45.16 KB · 20 files |
Extract pages 1–5 from a 100-page PDF extractPages() with the range "1-5". | 1 PDF × 100 pages | 7ms | 7.3ms | 8.65 KB |
Page tools
| Benchmark | Input | Median | p95 | Output |
|---|---|---|---|---|
Number every page of a 100-page PDF addPageNumbers() with the "page n of total" format. | 1 PDF × 100 pages | 32.3ms | 36.9ms | 177.4 KB |
Watermark every page of a 100-page PDF watermarkPdf() drawing diagonal "DRAFT" text on each page. | 1 PDF × 100 pages | 29.9ms | 31.5ms | 183.16 KB |
Packaging
| Benchmark | Input | Median | p95 | Output |
|---|---|---|---|---|
Package 50 PDFs into a ZIP JSZip generateAsync with the same defaults the site's batch download uses. | 50 PDFs × 3 pages | 5.5ms | 10.1ms | 277.63 KB |
Methodology
- Each benchmark runs 1 warm-up pass, then 7 timed runs; we report the median and 95th percentile.
- The code under test is
src/lib/converters/pdf.ts— the same module browsers download — with pdf-lib 1.17.1 and JSZip 3.10.1, the exact versions pinned in the shipping build. - The corpus is fully synthetic (seeded pseudo-random text; no customer or third-party files) and each file's SHA-256 is published in the corpus manifest.
- Reference environment: Node.js v23.7.0 on Apple M2 Pro (arm64, 10 cores).
Limitations — read this before comparing
- Timings come from a server-class JavaScript runtime on reference hardware. Your browser runs the same code, but phone and older-laptop timings will be slower; the numbers are best used to compare operations against each other and releases against each other.
- The corpus is text-only PDF. Scanned, image-heavy, encrypted, or malformed documents behave differently — expanding the corpus is planned work, and the schema is versioned so old results stay comparable.
- Browser-only operations (Canvas image conversion, PDF rendering to images, ffmpeg media work) are not yet in the Lab because they cannot run unmodified outside a browser.
Data downloads
- results.json — raw benchmark output (schema
filemorf-lab-results/1), CC BY 4.0. - corpus-manifest.json — every corpus file's page count, byte size, seed, and SHA-256.
Questions about the methodology, or a benchmark you want added? support@filemorf.com. Read more about how FileMorf is tested on the about page.