Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsThe fastest way to improve Pyppeteer on Lambda is to find which clock is slow: Lambda initialization, Chromium launch, navigation, or the page-specific readiness wait. Add timestamps for each phase, then optimize the phase your measurements identify. Use the earliest navigation condition that still guarantees correct data, reduce initialization work, reuse safe resources across warm invocations, and tune memory and timeout with load tests. Provisioned Concurrency can reduce predictable cold-start delay; neither it nor any browser setting makes a remote website respond faster.
Measure the four latency phases first
A single duration around your handler hides the cause of slowness. Log separate timestamps for:
- Handler entry and Lambda initialization (code download, runtime startup and module-level initialization).
- Chromium executable preparation and browser launch.
- Page creation and
goto()navigation. - The selector, function or other condition that means your job is actually complete.
Run several representative URLs during cold starts and warm invocations. Record duration, memory used, timeout or other failures, and whether the returned output is correct. AWS describes initialization as a distinct phase and notes that package size, initialization work and connection setup contribute to it. A warm result is not a permanent guarantee: Lambda can freeze and reuse an environment, then terminate it.
import time
from pyppeteer import launch
_t0 = time.perf_counter()
# Keep imports and other inexpensive, reusable setup outside the handler.
_browser = None
def mark(label, start):
now = time.perf_counter()
print({"phase": label, "seconds": round(now - start, 3)})
return now
async def handler(event, context):
global _browser
start = time.perf_counter()
mark("handler-entry", _t0)
if _browser is None:
launch_start = time.perf_counter()
_browser = await launch(
headless=True,
args=["--no-sandbox", "--disable-setuid-sandbox"]
)
mark("chromium-launch", launch_start)
page_start = time.perf_counter()
page = await _browser.newPage()
mark("new-page", page_start)
nav_start = time.perf_counter()
await page.goto(event["url"], {
"waitUntil": "domcontentloaded",
"timeout": 30_000
})
mark("navigation", nav_start)
ready_start = time.perf_counter()
await page.waitForSelector("main article", {"timeout": 10_000})
mark("application-ready", ready_start)
html = await page.content()
await page.close()
mark("total", start)
return {"statusCode": 200, "body": html}
Adapt the executable setup and error handling to your package. Do not allow pages, cookies or user data from one invocation to leak into another; invocation-specific state belongs inside the handler.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →#1 Best Overall
Choose the right navigation completion condition
Pyppeteer 0.0.25 documents goto() with waitUntil='load' as the default. It also documents domcontentloaded, networkidle0 and networkidle2. The network-idle conditions require 500 ms with no more than the configured number of connections. The shortest condition is not automatically correct.
Use domcontentloaded when the DOM is enough
If your extraction needs markup that is present as soon as the document is parsed, this can avoid waiting for images and other load handlers:
await page.goto(url, {
"waitUntil": "domcontentloaded",
"timeout": 30_000
})
Verify that the required content is present before returning. A page that renders its data only after JavaScript runs may need an additional wait.
Use load when load handlers or assets matter
Keep the default when your task depends on the browser’s load event, such as a page whose application finishes setup in a load handler. It may be slower because images, stylesheets and other resources participate in the event.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchUse network-idle conditions selectively
networkidle0 waits for no active connections and networkidle2 allows up to two. Analytics, long polling, advertisements and WebSockets can keep a page active indefinitely or make the condition unrelated to application readiness. Test the target site rather than assuming network idle means “data is ready.”
Wait for the state your job needs
A known selector or JavaScript predicate is often more precise than a general page event:
await page.goto(url, {"waitUntil": "domcontentloaded", "timeout": 30_000})
await page.waitForSelector("main article", {"timeout": 10_000})
# Or, for an application flag:
await page.waitForFunction("window.appReady === true", {"timeout": 10_000})
Pyppeteer documents a 30-second default navigation timeout and lets you change it. Increasing a timeout prevents premature failure; it does not make navigation faster.
Reduce Lambda initialization work
AWS states that the largest contributor to latency before function execution is initialization code. Import only modules needed by the handler, remove unused dependencies, and avoid eager work on paths that do not use it. Smaller deployment packages can reduce code-loading time. Measure browser-binary extraction or setup in your packaging model before changing it; moving files without measuring can add complexity without reducing latency.
Keep reusable setup outside the handler
Module-level imports and configuration are evaluated once per execution environment. This can help warm invocations, but the environment is disposable. Any module-level browser, cache or connection must tolerate a missing or closed resource and must not contain request-specific data.
Handle failed or stale browsers
If a reused browser has disconnected, discard it and launch a new one. Close each page in a finally block. Limit concurrent pages to what the configured memory and CPU can support; a global browser does not make unlimited parallel work safe.
Rank #3
Reuse Chromium and temporary files carefully
Lambda may reuse an environment and retain /tmp contents across freeze and thaw. Reuse can remove repeated launch or extraction work, but it is temporary and may end after a few hours or at any time. Treat every cache entry as optional and potentially stale. Never assume a browser process, page, cookie jar or login remains available. Clear or isolate session state when requests belong to different users.
The best browser-lifetime strategy depends on failure handling, concurrency and workload. Benchmark a browser kept for the environment against launching per invocation, measuring both cold and warm behavior and verifying that pages remain isolated.
Tune memory, timeout and concurrency from measurements
Browser automation can be CPU-bound during Chromium launch and rendering, or network-bound while waiting on a remote site. Compare duration, failures and billed resources at several memory settings instead of assuming more memory always improves navigation. AWS recommends reviewing the Max Memory Used field, using the open-source Lambda Power Tuning project, and load-testing timeout choices.
| Setting | What to measure | Common mistake |
|---|---|---|
| Memory | Cold launch, warm navigation, peak memory and cost at multiple sizes | Choosing a large value without checking duration and billed cost |
| Timeout | Normal and tail navigation times plus failure rate | Raising the limit and calling the invocation “faster” |
| Concurrency | Browser CPU, memory pressure, throttling and remote-site behavior | Sharing pages or session state between requests |
Provisioned Concurrency
Provisioned Concurrency pre-initializes execution environments for more predictable starts. It addresses Lambda initialization, not DNS, server response time or rendering time on the remote page. Compare its ongoing cost with the latency requirement and traffic pattern.
SnapStart
AWS describes SnapStart as providing startup performance as low as sub-second in eligible configurations. Eligibility and limitations change by runtime and deployment configuration. The documented limitations include no combination with Provisioned Concurrency, no EFS or S3 Files, and a 512 MB ephemeral-storage ceiling; some managed runtimes, including Node.js and Ruby versions listed by AWS, are unsupported. Check the current AWS eligibility page before designing around it. SnapStart targets startup initialization and does not shorten remote navigation.
Validate your Chromium and Pyppeteer package combination
Chromium must speak a compatible DevTools protocol to your installed Pyppeteer version and run on your Lambda architecture and runtime. The third-party chrome-aws-lambda repository shows a Puppeteer-oriented example and recommends at least 512 MB, with 1600 MB or more for its package use. That guidance is not proof of compatibility with Pyppeteer, every current Lambda runtime or your workload.
- Confirm the repository’s maintenance status and supported runtime.
- Match Chromium, Pyppeteer and architecture versions.
- Check deployment-package and layer limits.
- Run a cold-start test in the exact Lambda configuration.
- Do not copy Node/Puppeteer launch flags blindly into Python.
A repeatable optimization workflow
- Instrument handler entry, browser launch, page creation, navigation and readiness.
- Collect cold and warm samples for several real URLs, including failures and output checks.
- Select the earliest correct condition: a load event, DOM content, network idle, selector or function.
- Remove unused dependencies and defer expensive initialization.
- Test safe browser and
/tmpreuse with explicit cleanup and isolation. - Run memory and timeout comparisons, then load-test concurrency.
- Evaluate Provisioned Concurrency or eligible SnapStart only for the initialization phase.
- Re-test after every Chromium, Pyppeteer, runtime or packaging change.
Troubleshooting slow or failing invocations
Cold starts are slow but warm calls are acceptable
Inspect package size, import time, browser extraction and launch timestamps. Remove unused modules, defer setup, or evaluate Provisioned Concurrency. Do not expect a navigation-wait change to fix time spent before Chromium starts.
goto() waits until timeout
The page may maintain long-lived requests, so network-idle criteria never occur, or the site may be unreachable. Try the documented load or DOM event, then wait for a specific selector or function. Keep a timeout that reflects the workload and log the failing URL.
The selector wait times out
Check that the selector exists in the correct frame and appears after the chosen navigation event. Confirm the URL did not return a bot check, login page or error document. Capture diagnostic HTML or a screenshot in a non-production test path.
Chromium fails to launch
Check executable permissions, architecture, available ephemeral storage, memory and protocol compatibility. Verify that the binary actually supports the selected Lambda runtime; a package README’s Puppeteer example is not a Pyppeteer compatibility guarantee.
Free tools Windows power users keep installed
One-click scans. No signup required.
Warm invocations return another request’s state
Move cookies, pages, headers and extracted data into invocation-local variables. Clear or recreate the page between requests, and never rely on process lifetime for correctness.
More memory did not help
If navigation is network-bound, CPU increases may not matter. Compare phase timings and cost at several memory values, then optimize the readiness condition or remote request path instead.
Or skip the browser setup
If your goal is a clean website image or PDF rather than custom browser automation, ScreenshotNeo provides a single-call screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing status.
Use the API documentation at https://screenshotneo.com/docs/ for all options, including full-page lazy-image loading, CSS-element capture, device and retina settings, PDF controls, custom CSS and JavaScript, waits, request blocking, headers and cookies, geolocation, signed links, asynchronous webhooks, bulk capture and caching.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo includes an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots, and every feature is on every plan. Start with the free ScreenshotNeo account.
Cost and reliability considerations
Measure Lambda duration and billed memory together. A faster, higher-memory invocation can cost more or less depending on how much duration it removes. Include retries, failed navigations and cold-start frequency in your workload sample. Remote-site behavior, throttling and bot defenses can dominate results, so report your own cold and warm measurements rather than promising a universal percentage improvement.
Frequently Asked Questions
Does increasing the Pyppeteer navigation timeout speed up Lambda?
No. It only allows a slow or stalled navigation to run longer before failing. Speed comes from choosing a correct readiness condition and reducing work in the relevant phase.
Should I always use networkidle0 for complete pages?
No. Long polling, analytics and other persistent requests can prevent network idle or make it unrelated to the data you need. Prefer a selector or function that represents application readiness when possible.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Can Lambda SnapStart make a website load faster?
SnapStart targets eligible Lambda startup initialization. It does not reduce the remote site’s response, JavaScript execution or Pyppeteer navigation time.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

