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 Lambda | Riddle API | |
|---|---|---|
| Per-screenshot cost | ~$0.001 | ~$0.004 |
| Setup time | 4-10 hours | 10 minutes |
| Debugging (first month) | 2-8 hours | 0 |
| Maintenance (per quarter) | 1-4 hours | 0 |
| 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 Category | Self-Hosted | Riddle |
|---|---|---|
| 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.001 | N/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
| Feature | Self-Hosted | Riddle |
|---|---|---|
| Simple URL screenshots | Yes | Yes |
| Full Playwright API | Yes | Yes |
| Structured JSON steps API | Build yourself | Yes (/v1/run) |
| Multi-page scripts | Yes | Yes |
| Auth header pass-through | Yes | Yes |
| Cookie injection | Yes | Yes |
| PDF generation | Yes | Yes |
| Custom Chrome extensions | Yes | No |
| Zero infrastructure | No | Yes |
| Automatic updates | No | Yes |
| Works on Vercel/Cloudflare | No | Yes |
Riddle Pricing
30-second minimum
Multiple screenshots per job
No setup costs. No maintenance burden. No surprise debugging sessions at 2am.
Skip the Infrastructure
Get screenshots working in minutes instead of hours.