← Back to Home

The True Cost of Self-Hosted Puppeteer

Self-hosting looks cheaper on paper. But when you add up setup time, debugging hours, and maintenance burden, the math changes.

The Quick Version

Self-Hosted LambdaRiddle API
Per-screenshot cost~$0.001~$0.004
Setup time4-10 hours10 minutes
Debugging (first month)2-8 hours0
Maintenance (per quarter)1-4 hours0
Break-even point~3,000 screenshots (at $50/hr dev time)

If you're taking fewer than 3,000 screenshots per month, Riddle is cheaper.
Even at higher volumes, the maintenance burden often tips the scales.

Setup Time: The Hidden First Cost

Getting Puppeteer working in Lambda isn't a 5-minute npm install. Here's what you're signing up for:

Research the options (1-2 hours)

@sparticuz/chromium vs chrome-aws-lambda vs puppeteer-core. Which version works with which Node.js runtime? Stack Overflow has conflicting answers from different years.

Configure Lambda layers (1-2 hours)

Download the right Chromium binary. Create the layer. Configure layer ARN. Figure out why the layer isn't being found. Realize you need to match regions.

Debug the first deployment (1-3 hours)

"Unzipped size must be smaller than 262144000 bytes." Okay, try compression. "error while loading shared libraries." Missing dependencies. Add them. "spawn ENOMEM." Increase memory. "Task timed out." Increase timeout.

Handle edge cases (1-3 hours)

Some pages timeout. Some crash Chrome. Some need specific viewport sizes. Some require waiting for network idle. You discover these one at a time in production.

Total: 4-10 hours before you have something production-ready. At $50/hour, that's $200-500 just to get started.

Debugging: The Recurring Tax

Self-hosted Puppeteer on Lambda breaks in fun and creative ways:

Memory Crashes

Complex pages exhaust Lambda's memory. Chrome crashes silently. Your logs show nothing useful. You increase memory, costs go up, and it still happens occasionally.

Cold Start Timeouts

First request after idle takes 10+ seconds for Brotli decompression. API Gateway times out. Users see errors. You add retry logic.

Version Conflicts

Chromium 119 works with Puppeteer 21.5.2 but not 21.6.0. Node.js 18.20.1 breaks something that worked in 18.19.0. You spend hours bisecting versions.

Mysterious Failures

"Protocol error (Page.navigate): Target closed." What does that mean? The page loaded fine locally. Lambda's environment is just... different.

Budget 2-8 hours of debugging in your first month. After that, expect 1-2 hours per quarter dealing with breakages from runtime updates.

Maintenance: The Ongoing Burden

Even when it's working, self-hosted Puppeteer requires attention:

Runtime Updates

AWS deprecates Node.js versions. You have to migrate. Sometimes the new runtime breaks your Chromium setup. April 2024's Node.js 18.20 update broke Puppeteer for thousands of developers.

Security Patches

Chromium has vulnerabilities. You should update. But updating means testing compatibility again. So you don't update. Your Lambda runs a browser with known security issues.

Dependency Updates

@sparticuz/chromium releases new versions. Puppeteer releases new versions. Should you update? Will it break? Only one way to find out.

Monitoring & Alerts

You need to know when screenshots fail. Set up CloudWatch alarms. Track error rates. Investigate spikes. This is infrastructure you have to maintain.

The Math

Let's calculate the break-even point, assuming $50/hour developer time:

Cost CategorySelf-HostedRiddle
Initial setup (one-time)$250-500 (5-10 hrs)$0 (10 min)
First month debugging$100-400 (2-8 hrs)$0
Quarterly maintenance$50-200 (1-4 hrs)$0
Per screenshot (Lambda compute)~$0.001N/A
Per screenshot (Riddle)N/A~$0.004

Year 1 Break-Even

Setup ($350) + debugging ($250) + maintenance ($300) = $900 in hidden costs.

At $0.003 savings per screenshot, you need ~300,000 screenshots in year 1 just to break even.

Year 2+ Break-Even

Ongoing maintenance ($400/year) = ~133,000 screenshots per year to justify self-hosting.

That's ~11,000/month or ~365/day.

When Self-Hosting Makes Sense

We're not saying self-hosting is always wrong. It makes sense when:

Very High Volume

If you're taking 500,000+ screenshots per month, the per-screenshot savings add up. At that scale, infrastructure complexity is justified.

Specialized Requirements

Custom Chrome extensions, specific browser versions, or unusual configurations that a managed API can't provide.

You Already Have Infrastructure

If you're already running Kubernetes or have dedicated browser automation infrastructure, adding screenshot capability is incremental.

Compliance Requirements

Some industries require data to never leave your infrastructure. If screenshots contain sensitive data, self-hosting may be mandatory.

Feature Comparison

FeatureSelf-HostedRiddle
Simple URL screenshotsYesYes
Full Playwright APIYesYes
Structured JSON steps APIBuild yourselfYes (/v1/run)
Multi-page scriptsYesYes
Auth header pass-throughYesYes
Cookie injectionYesYes
PDF generationYesYes
Custom Chrome extensionsYesNo
Zero infrastructureNoYes
Automatic updatesNoYes
Works on Vercel/CloudflareNoYes

Riddle Pricing

from $0.004
Per job

30-second minimum

<$0.001
Per screenshot

Multiple screenshots per job

No setup costs. No maintenance burden. No surprise debugging sessions at 2am.

Full pricing details → | Maximize value →

Skip the Infrastructure

Get screenshots working in minutes instead of hours.