ScreenshotNeo

BlogHow-to

Browserless Screenshot Times Out on Slow Websites: How to Fix It

Diagnose which Browserless timeout is expiring, choose a page readiness condition, and fix slow captures without waiting blindly.

By the ScreenshotNeo team4 October 20267 min read

A Browserless screenshot timeout can expire while the REST request is running, while the page is navigating, while a selector or function is being awaited, or during the screenshot operation. First identify which stage failed. Then adjust that stage’s timeout and wait for the condition your capture actually needs. Increasing every timeout indiscriminately can make failures slower to detect without fixing a CAPTCHA, access-denied response, blank page, or expensive full-page capture.

Browserless documents the query parameter timeout as the budget for the entire REST operation, including waits. Navigation has its own gotoOptions.timeout; selector, function, and event waits have their own timing; BQL screenshot options have a screenshot timeout. The whole-request budget must leave room for navigation, readiness waits, and capture. Browserless does not establish one maximum that applies to all routes, deployments, and accounts, so check the live documentation for your endpoint and account.

1. Identify which timeout expired

Layer What it limits What to inspect
REST request timeout The complete operation, including waits Query parameter and total elapsed request time
Navigation gotoOptions.timeout Page navigation Navigation settings and the selected waitUntil event
Readiness wait A selector, function, or event condition The awaited selector or condition; confirm it exists on the target page
Screenshot operation The capture itself Screenshot options, full-page mode, image waiting, and screenshot timeout

Use the error context and request configuration to locate the expiring stage. A whole-request timeout can mask which inner operation was slow because it includes all of them. Browserless also notes that an HTTP 200 from its API does not necessarily mean the target website returned a successful status.

2. Choose a navigation condition that fits the page

The navigation completion event determines what Browserless waits for before moving on. Choose based on the content the screenshot needs:

waitUntil Waits for Useful when Watch out for
domcontentloaded Initial HTML parsing to finish The needed content appears early and remaining resources are not important Images, styles, or client-side content may still be loading
load The load event after dependent resources finish loading The capture needs the page’s usual loaded resources Slow resources can delay the event
networkidle0 No network connections for at least 500 ms The page becomes quiet and that is a useful readiness signal Long polling or persistent background requests can prevent idleness
networkidle2 No more than two network connections for at least 500 ms Some background connections remain open It still may not signal that the specific content you need is ready

If a site keeps connections open, an idle condition can time out even though the desired content is already visible. In that case, use a specific selector or application condition. Prefer the narrowest condition that reliably represents the content in your screenshot.

3. Wait for the content you need

A condition-based wait usually gives a more reliable capture than guessing a fixed delay. Browserless supports waiting for a selector, optionally requiring visibility, or waiting for a page function to become true. A fixed delay is available when time itself matters, such as allowing an animation to finish; it always consumes that delay even if the page becomes ready sooner.

Example Browserless REST configuration (JavaScript object illustrating the documented options; use it in the request body format required by your Browserless screenshot route):

const options = {
  gotoOptions: {
    timeout: 45000,
    waitUntil: "domcontentloaded"
  },
  waitForSelector: {
    selector: "main article",
    options: {
      visible: true,
      timeout: 20000
    }
  },
  screenshot: {
    fullPage: false,
    waitForImages: false
  }
};

These values are an example budget, not a Browserless recommendation or a guarantee that a particular target will finish in that time. Keep the total request timeout higher than the time you allocate to navigation plus readiness and capture. Check the current endpoint documentation for the exact request schema: Browserless offers different routes and request forms.

4. Set a deliberate total time budget

Browserless’s timeout guide advises using realistic timeout values: a low budget may fail on slow content, while an unnecessarily high budget delays error detection. Budget for each stage and leave enough overall time for all of them. For example, if navigation may take 45 seconds and the selector may take another 20 seconds, the request-level budget must exceed their combined time plus capture and overhead.

Browserless states that “The query parameter timeout applies to the entire request, including all wait operations.” Treat the query parameter as the outer deadline, not a replacement for navigation or wait configuration. Monitor total request time in your own workflow and handle timeout errors explicitly.

5. Use bestAttempt only for acceptable partial captures

Browserless documents bestAttempt: true as a way to proceed after some awaited events time out, returning the page state available at that point. This can be useful when a partial result has value. It does not mean that the required content loaded: inspect the screenshot or validate the expected content before using the result.

6. Check for blocking and expensive capture work

A longer timeout will not necessarily fix a CAPTCHA, blank or white page, access-denied or 403 response, or a missing element. Browserless documents these as signs that automation may be blocked or the target response may not be what the workflow expects. Check the page result and target response before changing timeout values again.

Capture options can also add work:

  • fullPage captures beyond the initial viewport and can require more rendering and image work. Turn it off if the desired output is only the visible viewport.
  • waitForImages waits for images to load. Enable it only when all images are required; otherwise it can hold up a capture on slow or broken image resources.
  • Browserless shared configuration supports rejecting resources or request patterns. Block only resources confirmed to be unnecessary for the visual result. Blocking stylesheets, fonts, or scripts the page needs can make the screenshot inaccurate.

For BQL, Browserless documents a default screenshot.timeout of 30 seconds (30,000 ms). This is the documented default for that screenshot operation, not a universal maximum for the full REST request or every deployment. Check the current BQL and route documentation before relying on a setting or ceiling.

7. Troubleshooting checklist

Symptom Likely cause Next step
The whole API request times out The outer timeout budget is shorter than navigation, waits, and capture combined Measure the stages, then set a realistic request budget with room for each stage
Navigation times out but the request budget remains The navigation event takes too long, or the chosen event never occurs Adjust gotoOptions.timeout; choose a more appropriate waitUntil condition
Selector wait times out The selector is wrong, absent, hidden, or never rendered Confirm the selector on the target page; use visibility only when visible content is required
networkidle0 never completes Persistent requests or long polling keep the network active Use a meaningful selector or function condition, or consider networkidle2 if it fits the page
Screenshot operation times out Capture work is too large or the screenshot-specific budget is too low Check screenshot timeout settings; disable unneeded full-page or image waiting options
Screenshot is blank or white The site may be blocked, failed to render, or returned a page without the expected content Inspect the target result and browser output; diagnose blocking rather than only extending the timeout
CAPTCHA, 403, or access denied The target may be blocking automation or rejecting the request Confirm the target response and whether access is permitted; more waiting does not resolve an access restriction
API reports success but screenshot content is wrong API HTTP status does not establish that the target returned a successful page Validate the captured page or expected content independently
Capture is slow after the page appears ready Full-page rendering, image waits, or unnecessary resources add work Capture only the required area and wait only for resources needed in the output

8. Reliable production handling

  1. Log the endpoint, target URL, timeout settings, selected navigation condition, and which readiness wait was used.
  2. Separate navigation failures from selector/function wait failures and screenshot failures in error handling; changing the correct layer is easier when the stage is visible.
  3. Validate the result for expected content. A returned image or successful API status alone does not prove the target page loaded correctly.
  4. Use bestAttempt only when a partial page is acceptable and downstream checks can reject incomplete captures.
  5. Set an overall deadline appropriate to your application. Very high timeouts tie up workers and delay failure reporting; overly low values reject legitimate slow pages.
  6. Use resource rejection conservatively and verify that removed resources do not alter layout or hide the content you need.

Or skip the browser setup

If you need screenshots without configuring browser waits and capture plumbing, ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for parameters.

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}`);
  • Cookie banners are accepted like a visitor and removed before the shot, along with 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off.
  • Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers report the page verdict and billing status.
  • An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf.
  • The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan.

Sign up free for 1,000 screenshots a month, with no card required.

Frequently asked questions

Is Browserless’s 30-second screenshot timeout the limit for every request?

No. The documented 30-second default applies to the BQL screenshot operation. It does not establish a universal limit for the full REST request, every route, or every deployment.

Should I always use network idle for screenshots?

No. Network-idle conditions can be unsuitable for pages with persistent background requests. Use an application-specific condition when it better signals that the needed content is ready.

Does bestAttempt guarantee a complete screenshot?

No. It allows continuation after some awaited events time out. Check whether the returned page state contains the content your workflow requires.

Sources