Originally published at htpbe.tech. The version on htpbe.tech stays in sync with the latest detection algorithm — refer to it for the canonical text.
The first time you run a PDF verification pipeline at production volume on a single Node.js worker, you discover the same three failures in roughly the same order: V8 heap exhaustion under concurrent load, a Vercel 413 on anything above 4.5 MB, and a worker that gets slower and slower as the event loop fills with paused Buffer.concat chains. None of these are bugs in your code — they are the predictable cost of the “FormData → full buffer → analyze” pattern that almost every PDF tutorial starts with.
This guide is for backend engineers integrating PDF tamper detection into a Node service that has to handle real upload volume. The honest framing up front: you cannot make pdf-lib itself stream — the PDF format needs the xref table at the end of the file, and the parser needs the whole thing resident. What you can do is control the three things that actually cause production failures: how many bytes you ever pull into the worker, where the bytes live during the slow upload phase, and how many parses run in parallel. We will walk through why the naive pattern dies, the two-step upload pattern HTPBE uses internally to decouple upload throughput from analysis throughput, a clean Node 20+ implementation with backpressure and a hard byte cap, and the concurrency story across Vercel, Fly.io, Coolify, and a self-hosted Fastify worker. (For the conceptual API tour first, see the Node.js integration guide; for the queue/fan-out angle, see batch PDF verification with queues.)






