← Compare to Self-Hosted

AWS Lambda Chromium Binary Size Limit

Why your Puppeteer deployment fails and what to do about it

The Error

Unzipped size must be smaller than 262144000 bytes

# Or you might see:
Resource handler returned message: "Unzipped size must be smaller
than 262144000 bytes" (RequestToken: xxx, HandlerErrorCode: InvalidRequest)

This happens when your Lambda deployment package (including dependencies) exceeds 250 MB unzipped. Chromium alone is ~280 MB. You're stuck before you even start.

Why This Happens

Lambda Limits

  • 250 MB unzipped deployment size
  • 50 MB zipped upload limit
  • Lambda Layers count toward this

Chromium Size

  • Full Chromium: ~280 MB
  • chromium-min: ~45 MB (stripped)
  • + Puppeteer/Playwright: ~50 MB

Even with stripped-down Chromium builds, you're constantly fighting the limit. Add your application code and any other dependencies, and you hit the wall fast.

Traditional "Solutions" (And Their Problems)

1. Use Lambda Layers

Split Chromium into a separate Layer to stay under the limit.

Problems:
  • Layers still count toward 250 MB total
  • Layer management adds deployment complexity
  • Version mismatches between Puppeteer and Chromium
  • Cold starts are still brutal (~8-15 seconds)

2. Use @sparticuz/chromium

A stripped-down Chromium build for Lambda (~45 MB).

npm install @sparticuz/chromium puppeteer-core
Problems:
  • Missing fonts, emoji, some rendering features
  • Maintenance burden when Chromium updates
  • Still ~100 MB with Puppeteer, leaving little room for your code
  • Cold starts still 5-10 seconds

3. Use Container Images

Lambda supports container images up to 10 GB.

Problems:
  • ECR costs and complexity
  • Slower cold starts (pulling larger images)
  • More infrastructure to manage
  • Still dealing with Chrome memory issues

The Simpler Solution: Don't Run Chrome in Lambda

Instead of fighting Lambda limits, use an API that runs Chrome elsewhere:

// Your Lambda function - simple HTTP call, no Chrome needed
const response = await fetch("https://api.riddledc.com/v1/run", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ url: "https://example.com" })
});

const screenshot = await response.arrayBuffer();
// Done. No Chromium. No layers. No size limits.
0 MBAdded to your deployment
~3sScreenshot returned
$0.004Per screenshot

Time Comparison

ApproachSetup TimeCold StartOngoing Maintenance
Puppeteer + Layers4-8 hours8-15 secondsMonthly updates
@sparticuz/chromium2-4 hours5-10 secondsVersion tracking
Container Image4-6 hours10-20 secondsECR + Image builds
Riddle API5 minutes0 (no Chrome)None

Skip the Lambda Chrome Struggle

Get screenshots without managing Chromium infrastructure.