Ghostscript gs: Compress and Downsample PDFs
gs -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -o out.pdf in.pdf rewrites a PDF with downsampled images to shrink it.
When a generated PDF artifact is too large for CI storage or download, Ghostscript's pdfwrite device with a -dPDFSETTINGS preset is the standard way to compress it.
What it does
Ghostscript reads the PDF and re-emits it through the pdfwrite device. -dPDFSETTINGS picks a preset (/screen, /ebook, /printer, /prepress) that controls image downsampling resolution and JPEG quality, trading size against fidelity.
Common usage
# strong compression (web/email)
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 \
-dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH -dQUIET \
-sOutputFile=out.pdf in.pdf
# custom downsample resolution
gs -sDEVICE=pdfwrite -dDownsampleColorImages=true \
-dColorImageResolution=150 -dNOPAUSE -dBATCH \
-sOutputFile=out.pdf in.pdfOptions
| Flag | What it does |
|---|---|
| -sDEVICE=pdfwrite | Output device: write a PDF |
| -dPDFSETTINGS=/screen | Smallest, ~72 dpi images |
| -dPDFSETTINGS=/ebook | Medium, ~150 dpi (good default) |
| -dPDFSETTINGS=/printer | /prepress | Higher quality, ~300 dpi |
| -sOutputFile=<f> / -o <f> | Output path (-o implies -dNOPAUSE -dBATCH) |
| -dNOPAUSE -dBATCH | Run non-interactively and exit |
In CI
Always pass -dNOPAUSE -dBATCH (or use -o) so Ghostscript does not pause for input and hang the job. Start with /ebook; drop to /screen only if the output stays readable. Compare sizes before and after, since a PDF that is mostly vector/text may not shrink.
Common errors in CI
"gs: command not found" means Ghostscript is not installed; apt-get install -y ghostscript. "Error: /undefinedfilename ... in.pdf" or "Unable to open the initial device" usually means a wrong input path or a missing -sDEVICE. Font warnings like "Can't find (or can't open) font file" are often non-fatal substitutions; install the gsfonts package to silence them. A gs that "hangs" almost always lacks -dBATCH.