Command-line batch tools: Ghostscript and Poppler
for f in *.pdf; do gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dCompatibilityLevel=1.7 -dPDFSETTINGS=/ebook -sOutputFile="compressed/$f" "$f"; done
The -dPDFSETTINGS parameter controls compression aggressiveness: /screen (lowest quality/size), /ebook, /printer, /prepress (highest quality).
Batch convert to PDF/A:
gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dPDFA=2 -dPDFACompatibilityPolicy=1 -sColorConversionStrategy=UseDeviceIndependentColor -sOutputFile=output.pdf input.pdf
Poppler utilities provide file-by-file PDF processing tools:
- pdfinfo: extract metadata (title, author, page count, PDF version)
- pdftotext: extract text content to a file
- pdfimages: extract embedded images
- pdftoppm: rasterise pages to PPM/PNG/JPEG
- pdffonts: list all fonts and their embedding status
- pdfseparate / pdfunite: split and merge PDFs
All Poppler utilities accept a single PDF path — wrap in a shell loop or parallel for batch use. Install on macOS via brew install poppler; on Ubuntu/Debian via apt install poppler-utils.Python libraries: PyMuPDF and pikepdf
fitz) is the fastest Python PDF library for reading and rendering:
import fitz, glob
for path in glob.glob("inbox/*.pdf"):
doc = fitz.open(path)
for i, page in enumerate(doc):
text = page.get_text()
pix = page.get_pixmap(dpi=150)
pix.save(f"thumbs/{i}.png")
doc.close()
PyMuPDF excels at text extraction, page rendering, annotation processing, and metadata manipulation. It is notably fast due to MuPDF's C core. pymupdf.readthedocs.io
pikepdf (bindings to QPDF) provides low-level access to the PDF object structure — ideal for operations that need to manipulate PDF internals: removing permissions, rewriting cross-reference tables, losslessly compressing object streams, or stripping metadata:
import pikepdf, glob
for path in glob.glob("inbox/*.pdf"):
with pikepdf.open(path) as pdf:
# Remove author metadata
del pdf.docinfo["/Author"]
pdf.save(path.replace("inbox/", "cleaned/"))
pikepdf.readthedocs.io
pdfplumber and Camelot are specialised for text and table extraction from PDFs, not general batch operations — but they integrate well into Python batch pipelines. See the tables guide for extraction tool comparisons.
Parallel processing — For large batches, parallelise with Python's multiprocessing.Pool or concurrent.futures.ProcessPoolExecutor. PDF operations are CPU-bound (not I/O-bound) so true parallel processing (multiple processes, not threads) gives near-linear speedup up to core count.iText and Apache PDFBox for JVM-based batch workflows
PdfCopy, PdfMerger, and stamper APIs handle batch merge/split workflows. iText's signing API supports PAdES signatures suitable for batch signing workflows. iText requires a commercial licence for non-AGPL use.
Apache PDFBox (pdfbox.apache.org) is the primary open-source, Apache-licensed Java PDF library. It covers text extraction, image extraction, PDF splitting/merging, basic form filling, and digital signing. PDFBox is the right choice for JVM batch workflows where a commercial licence is not acceptable. The PDFMergerUtility and Splitter classes handle common batch merge/split patterns.
Batch signing with iText — For signing thousands of PDFs in a batch, iText's PdfSigner API with an HSM-backed or cloud-signing integration handles cryptographic signing at scale. Key considerations: signing certificate validity, OCSP/CRL embedding for LTV (long-term validation), and thread safety if parallelising signing operations.