Skip to content
Encoding2026-10-14Begin4 min read

How to Merge PDFs: 3 Ways Compared (Local, CLI, Desktop)

Combining several PDFs into a single file is a constant need: sending a contract with its attachments, archiving a stack of scans, assembling a report chapter by chapter. This post compares three approaches and shows how to verify that a tool isn't quietly uploading your files.

Why merge tools deserve extra scrutiny

The files people merge tend to be contracts, ID scans, and financial records — exactly the documents that should never land on a stranger's server. To tell whether an online merge tool really runs locally, the method is always the same: open the DevTools Network panel, drop a file in, and watch for outgoing requests. A genuinely client-side tool fires none.

Three approaches compared

ApproachBest forBarrier to entry
In-browser local merge (ToolVault PDF Merge)Occasional merges, no software to installLowest
Command line qpdf / pdftkScripting, batches, CIRequires a CLI environment
Desktop software (Acrobat etc.)Heavy office use, editing needsInstall + paid
  • qpdf is the de facto standard for command-line merging: qpdf --empty --pages a.pdf b.pdf -- out.pdf does it in one line, fast and scriptable. The catch is that Windows users have to set up an environment first.
  • Desktop software is the most capable option (page-level editing, bookmark merging), but installing a heavyweight app for an occasional merge rarely pays off — and many "free" editions stamp a footer watermark on the result.
  • In-browser local merge (ToolVault PDF Merge) keeps working after the page loads even if you go offline — the bytes are copied between in-memory objects handled by pdf-lib, and the output downloads straight from the browser.

Three practical details of merging

Order follows the list order

Most tools concatenate in the order files were added. ToolVault's merge page has up/down arrows to reorder the list and shows each file's page count — before merging, check the expected total (pages in file 1 + pages in file 2 + …) to catch the silent failure of a file that simply never got appended.

Encrypted files fail silently

A password-protected PDF (one with an encryption dictionary) can't be parsed directly. A good tool fails with a clear error instead of emitting a corrupt output file. When you hit that error, decrypt first with the owner password (qpdf --decrypt in.pdf out.pdf), then merge.

Mixed page sizes are normal

A4 mixed with Letter, portrait mixed with landscape — all perfectly legal in a merged PDF, because every page in a PDF carries its own dimensions. If you need uniform pages, that's the job of a page-scaling feature, not the merger's. Don't expect a merge tool to do it as a side effect.

FAQ

Merged file came out bigger? Plain concatenation does no re-encoding, so the size ≈ the sum of the inputs. To shrink it further, compress (PDF Compress) — keeping merge and compress as two separate steps gives you far more control.

Can I merge only part of each file? That's a split-plus-merge combo: extract the ranges first with PDF Split, then merge the extracts.

Does merging work on a phone? Yes. Modern mobile browsers have plenty of memory for typical documents of a few MB to a few dozen MB; for scanned collections in the hundreds of MB, move to a desktop.

Implementation notes

Pitfalls from building a merge tool: pdf-lib's copyPages handles PDFs with cross-reference streams (what most scanners output) well, but throws on a damaged xref table instead of skipping it — so the tool must load each file as a pre-check and name the exact file that's broken. Otherwise the user faces a bare "merge failed" with nothing to debug. Separately, older iOS Safari lacks Blob.arrayBuffer and needs a FileReader fallback — a universal snag for file tools on mobile.

Bottom line

For occasional merges, an in-browser local tool is the least hassle (ToolVault PDF Merge — files never leave the machine); for scripting, qpdf is irreplaceable; consider desktop software only for heavy editing. Whichever route you take, check the tool's behavior in the Network panel first — including ours.