Why I stopped running headless Chrome to generate images
Every SaaS eventually needs to generate an image or PDF somewhere — an OG card for a blog post, a chart for a weekly email digest, an invoice PDF, a certificate. The default answer is always "spin up Puppeteer/Playwright." I did that for two years.
Here's the actual cost nobody tells you about:
Cold starts kill you. A headless Chrome instance takes 1-3s just to boot, before it even renders anything.
Fonts are a nightmare. Your local dev machine has fonts installed your production container doesn't. Docker image bloats to 1GB+ just for font packages.
Memory leaks under load. Chrome instances don't always clean up. At scale you're babysitting a process pool.
Server clustering. The moment you need this to survive real traffic, you're running a fleet of browser workers just to turn HTML into a PNG.
The fix that actually worked: treat rendering as a stateless API call, not infrastructure you own. Send code/content (HTML, Tailwind, Markdown, a Chart.js payload, even LaTeX), get back a PNG/JPEG/PDF. No browser to manage, no fonts to install, sub-second response times because there's no cold start.
Where this pattern pays off immediately:
OG images generated at request time per blog post/product — bumps CTR without a design pipeline
Chart images for email — you can't run JS inside an email client, so render the chart server-side and embed the image
Invoice/receipt PDFs — wire it straight to your payment webhook, get a branded A4/Letter PDF back instantly
Shareable certificates — course completions, milestones — personalized and rendered on demand, which is what actually drives the LinkedIn/Twitter shares
If you're maintaining a Puppeteer fleet right now just to generate images, you're solving an infra problem that's already been solved. Happy to answer questions if anyone's migrating off headless browser rendering — built Renderfy around exactly this.
