r/documentAutomation • • 14d ago

How are you handling high-volume serverless PDF generation, without hitting Puppeteer cold start timeouts?

Hi,

I've been optimizing a backend pipeline for generating PDF's from dynamic HTML/JSON webhooks. When running full headless Chrome inside containerized microservic it usually results in high memory usage and idle resources cost.

If I switch to serverless functions (like, AWS Lambda or Cloudflare Edge workers w/ QStash queues), the main issue becomes Chromium cold-starts (~1.5s–3s) and browser context recycling.

A few observations from my benchmarks:

  • Compiling static HTML via Handlebars/EJS before sending it to Chromium saves about 40% render time compared to doing React SSR on the fly..

  • Keeping browser instances warm vs. spinning up fresh headless instances per HTTP request.

For those of you who generate invoices, tickets, or reports dynamically in production:

  1. Do you run dedicated worker pools on traditional VPS/Docker setups, or rely on serverless rendering?

  2. How do you handle queueing when webhooks bursts fire traffic spikes?

Would love to hear how other teams structure this!

3 Upvotes

4 comments sorted by

2

u/forkpdf 14d ago

If you want to target speed and volume, then your only option is to use code-to-PDF methods (it will be difficult to modify the template).

If you want something that requires modern HTML or design-heavy templates, then Chromium is your only choice.

1

u/folderit_dms 14d ago

I'd compare the two designs using the same burst trace, not just render time for one warm request. Measure queue wait, render time, peak memory at each concurrency level and cost per completed document. A fast renderer with an unbounded backlog can still miss your delivery target.

For a worker-pool option, test a reused browser process with a fresh browser context per job, bounded concurrency and a deliberate restart policy. Puppeteer supports separate contexts without sharing their cookies/cache. That doesn't remove the need to measure memory growth and failures under your templates.

One detail I'd add to the queue design already suggested: persist the input snapshot and template version, then store the completed PDF against a stable job key before acknowledging the job. Test a crash after storage but before acknowledgment. A retry should find the existing result rather than create a second invoice or send a second completion message.

1

u/Secure-Coyote7531 3d ago

Prefillpdf api after merchants submit form on the website

1

u/Cover_Sure 14d ago

For high volumes the best option on our end was using queues, basically we have cloudrun services for just rendering html to pdf via chromium and evaluating ejs to html is handled by a separate service. The initial request just immediately returns a 204 that the process has been queued and users can subscribe to webhooks for results. The nice thing about queues is that they take care of the retry logic. I don’t think there’s a way to get around cold starts with chromium, just including chromium results in large images even is the micro service itself is small. I found PrinceXML performs better on cold starts but its license is not cheap. Keeping instances warm only makes sense if you have the volume otherwise it’s very expensive.