FAQ
Below you will find answers to our most commonly asked questions about Browser Rendering.
For pricing questions, visit the pricing FAQ. For usage limits questions, visit the limits FAQ. If you cannot find the answer you are looking for, join us on Discord ↗.
This error typically occurs because your Puppeteer launch is not receiving the browser binding. To resolve this error, pass your browser binding into puppeteer.launch.
This error (Unable to create new browser: code: 429: message: Browser time limit exceeded for today) indicates you have hit the daily browser-instance limit on the Workers Free plan. Workers Free plan accounts are capped at 10 minutes of browser use a day. Once you exceed that limit, further creation attempts return a 429 error until the next UTC day.
To resolve this error, upgrade to a Workers Paid plan which allows for more than 10 minutes of usage a day and has higher limits. If you recently upgraded but still see this error, try redeploying your Worker to ensure your usage is correctly associated with your new plan.
A 422 Unprocessable Entity error usually means that Browser Rendering wasn't able to complete an action because of an issue with the site.
This can happen if:
- The website consumes too much memory during rendering.
- The page itself crashed or returned an error before the action completed.
- The request exceeded one of the timeout limits for page load, element load, or an action.
Most often, this error is caused by a timeout. You can review the different timers and their limits in the REST API timeouts reference.
If your screenshots, PDFs, or scraped content are missing elements that appear when viewing the page in a browser, the page likely has not finished loading before Browser Rendering captures the output.
JavaScript-heavy pages and Single Page Applications (SPAs) often load content dynamically after the initial HTML is parsed. By default, Browser Rendering waits for domcontentloaded, which fires before JavaScript has finished rendering the page.
To fix this, use the goToOptions.waitUntil parameter with one of these values:
| Value | Use when |
|---|---|
networkidle0 | The page must be completely idle (no network requests for 500 ms). Best for pages that load all content upfront. |
networkidle2 | The page can have up to 2 ongoing connections (like analytics or websockets). Best for most dynamic pages. |
REST API example:
{ "url": "https://example.com", "goToOptions": { "waitUntil": "networkidle2" }}If content is still missing:
- Use
waitForSelectorto wait for a specific element to appear before capturing. - Increase
goToOptions.timeout(up to 60 seconds) for slow-loading pages. - Check if the page requires authentication or returns different content to bots.
For a complete reference, see REST API timeouts.
Not yet. Local development currently has the following limitation(s):
- Requests larger than 1 MB are not supported.
Yes, Browser Rendering requests are always identified as bot traffic by Cloudflare. Cloudflare does not enforce bot protection by default — that is the customer's choice.
If you are attempting to scan your own zone and want Browser Rendering to access your website freely without your bot protection configuration interfering, you can create a WAF skip rule to allowlist Browser Rendering.
You must be on an Enterprise plan to allowlist Browser Rendering on your own website because WAF custom rules require access to Bot Management fields.
-
In the Cloudflare dashboard, go to the Security rules page of your account and domain.
Go to Security rules -
To create a new empty rule, select Create rule > Custom rules.
-
Enter a descriptive name for the rule in Rule name, such as
Allow Browser Rendering. -
Under When incoming requests match, use the Field dropdown to choose Bot Detection ID. For Operator, select equals. For Value, enter
128292352. -
Under Then take action, in the Choose action dropdown, select Skip.
-
Under Place at, select the order of the rule in the Select order dropdown to be First. Setting the order as First allows this rule to be applied before subsequent rules.
-
To save and deploy your rule, select Deploy.
No. Browser Rendering requests originate from Cloudflare's global network and you cannot configure per-request IP rotation. All rendering traffic comes from Cloudflare IP ranges and requests include automatic headers, such as cf-biso-request-id and cf-biso-devtools so origin servers can identify them.
There is no fixed limit on the number of requests per browser session. A single browser can handle multiple requests as long as it stays within available compute and memory limits.
Yes. If your webpage or PDF requires a font that is not pre-installed, you can load custom fonts at render time using addStyleTag. This works with both the REST API and Workers Bindings. For instructions and examples, refer to Use your own custom font.
If you are hitting concurrency limits, or want to optimize concurrent browser usage with the Workers Binding method, here are a few tips:
- Optimize with tabs or shared browsers: Instead of launching a new browser for each task, consider opening multiple tabs or running multiple actions within the same browser instance.
- Reuse sessions: You can optimize your setup and decrease startup time by reusing sessions instead of launching a new browser every time. If you are concerned about maintaining test isolation (for example, for tests that depend on a clean environment), we recommend using incognito browser contexts ↗, which isolate cookies and cache with other sessions.
If you are still running into concurrency limits you can request a higher limit ↗.
No. Cloudflare processes content ephemerally and does not retain customer-submitted HTML or generated output (such as PDFs or screenshots) beyond what is required to perform the rendering operation. Once the response is returned, the content is immediately discarded from the rendering environment.
This applies to both the REST API and Workers Bindings (using @cloudflare/puppeteer or @cloudflare/playwright).
For the REST API, generated content is cached by default for five seconds (configurable up to one day via the cacheTTL parameter, or set to 0 to disable caching). This cache protects against repeated requests for the same URL by the same account. Customer-submitted HTML content itself is not cached.
For Workers Bindings, no caching is used. Content exists only in memory for the duration of the rendering operation and is discarded immediately after the response is returned.
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2026 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark
-