# Puppeteer Lambda Cold Start

Puppeteer cold starts on Lambda can take 8-15 seconds because the function has
to load code, extract Chromium, spawn browser processes, and navigate before
the first screenshot starts.

Plain text for agents: https://riddledc.com/guides/puppeteer-lambda-cold-start/markdown.md

## The Problem

A typical cold start timeline can spend seconds before the first page
navigation begins:

```text
0.0s  - Lambda container starts
1.5s  - Application code loads and Puppeteer imports
3.0s  - browser.launch() starts
8-12s - Chromium extracts and starts
12-15s - First page.goto() begins
```

## Why Cold Starts Are So Slow

Chromium extraction to `/tmp` costs several seconds on cold start. Chromium
also spawns multiple processes, uses substantial memory, and cannot rely on a
shared warm browser pool across new Lambda instances.

## Common Mitigation Attempts

### Provisioned Concurrency

Provisioned Concurrency keeps instances warm, but it costs money around the
clock and does not avoid cold starts when traffic exceeds the provisioned pool.

### Keep-Warm Pings

Scheduled pings only keep one instance warm. A second concurrent request can
still pay the full cold start cost.

### Increase Memory

More memory gives Lambda more CPU and can shorten browser launch time, but it
does not remove Chromium extraction or process startup.

## Alternative: No Cold Start at All

Instead of optimizing Puppeteer cold starts, avoid running Chrome in Lambda:

```js
const response = await fetch("https://api.riddledc.com/v1/run", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.RIDDLE_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ url })
});

const screenshot = await response.arrayBuffer();
```

Riddle handles the browser outside the Lambda runtime, giving more consistent
screenshot timing without Chromium cold start overhead in the function.

## When Self-Hosting Still Makes Sense

Self-hosting can still make sense for high-volume warm workloads, custom
Chrome extensions, strict compliance needs, or specific browser versions. For
sporadic workloads and prototypes, an API is simpler.

