Skip to content

Date: 2026-08-17

Talbot noticed Cursor Stripe receipts run ~10x the size of near-identical Anthropic ones, and a BMO Investorline statement corpus had months running ~6x bigger than others. Research + validate a lossless PDF compression tool (borrow, don’t build), confirm no readability loss on real receipts + the 12 BMO 2025 statements.

The size gaps were never a compression-settings problem. qpdf/zopfli lossless recompression tops out at ~7–15% — content streams are already zlib-deflated, near their own entropy limit. The real cause: each affected PDF embeds a print-resolution raster image (e.g. a 2550×300px header banner) wildly oversized for screen/archival use. Confirmed by comparing embedded-image byte totals between a small and a large file of the same document type.

Fix: Ghostscript’s /screen preset (72dpi image downsampling) — leaves text as vector (100% lossless, verified via PyMuPDF text-extraction string-equality across every page of every test file) while discarding the oversized image resolution. On the 12 BMO 2025 statements: 14.47MB → 2.09MB (6.9x). Compared head-to-head against /ebook (150dpi) — not a close call, /ebook runs ~45% larger overall (3.04MB, 4.8x). /printer (300dpi) is a third, milder fallback if image fidelity ever needs to be higher.

Ghostscript needed sudo apt install ghostscript — Talbot ran it directly (no password available in-agent-session). qpdf was installed without sudo via apt-get download qpdf libqpdf29t64 + dpkg-deb -x into ~/.local/{bin,lib} — useful pattern for any Ubuntu package when sudo isn’t available: bypasses the package manager, no root needed.

pdfcompress (~/utils/pdfcompress/, on PATH via ~/.local/bin/pdfcompress):

Terminal window
pdfcompress in.pdf out.pdf # default: Ghostscript /screen, lossy images/lossless text
pdfcompress --lossless in.pdf out.pdf # qpdf recompress only, nothing touches images
pdfcompress --batch src_dir/ dst_dir/ # recursive, mirrors subfolder structure, prints per-file + total

Full findings/benchmarks: Core/IT/Utils/External/pdfcompress.md.

  • pdfcompress.md moved Custom/ → External/ (thin wrapper over external binaries, not custom-built logic) — pdftext.md stays in Custom/ (real installed uv-managed package, different shape).
  • Trimmed the duplicated benchmark tables out of Utilities.md’s PDF-compression section to a 2-line pointer at pdfcompress.md (SSOT).

Core/IT/Utils/Custom/rename-receipts.md pointed at “Core/Processes/Tasks/File-Naming-Upgrade.md for the full decision trail” — that task had actually completed 2026-07-29 and its task file was correctly deleted per the normal lifecycle; the pointer just never got updated to the log. Repointed it at Core/Processes/Logs/2026-07-29_File-Naming-Reference-Artifacts.md. New open item found in the same pass: Statements\Investments\ was never in rename_receipts’ scope and uses a different naming convention (AccountNumber_MMYYYY.pdf) than the Naming System.md §4 standard used elsewhere — flagged, not resolved.

Follow-on tasks spun out (not part of this task’s scope)

Section titled “Follow-on tasks spun out (not part of this task’s scope)”
  • Core/Accounting/Tasks/PDF-Compression-Rollout.md — batch-apply pdfcompress to the broader accounting corpus (Rogers bills, remaining statement types), compress-then-rename order.
  • Core/Processes/Tasks/File-Naming-Vault-Wide-Rollout.md — resolve the Statements\Investments\ convention question + the still-deferred vault-wide retroactive rename.

12 BMO 2025 statements + nov.PDF/dec.PDF renamed in place to match the existing 21414578_MMYYYY.pdf pattern (uncompressed originals; compression only applied to the c:\tmp\FSS-BMO\ showcase output, not the source folder).