Skip to main content
Sending Fetch requests one at a time leaves most of your plan idle. Run them in parallel, with as many in flight as your plan’s concurrency allows, and a list of URLs finishes in a fraction of the time. Each response tells you that number in its Concurrency-Limit header. Uses: Fetch with concurrency headers, the Python SDK and the Node.js SDK

Ask your AI agent

With the Zenrows MCP server connected to Claude, Cursor or any MCP client, paste this prompt. Your agent picks the right Zenrows tools and settings on its own.
Your agent sends the list as one Batch job, so the same prompt scales from four URLs to thousands.

Size a worker pool to your plan

Make one request, read Concurrency-Limit, then run that many workers over the rest of the list. Every worker reuses the same pattern: send, check, parse.

Example output

Results print in the order they finish, not the order of the list:

Let the SDK queue requests for you

The Zenrows SDKs keep an internal queue: fire every request at once and the client keeps concurrency of them in flight. retries re-sends transient failures. Install with pip install zenrows or npm install zenrows.
Output, in list order:
Set concurrency to your plan’s Concurrency-Limit. Use one client for the whole run, so every request shares the same queue.

Send very large lists to Batch

For thousands of URLs, or jobs you want to run without keeping a process alive, send the list to Batch. Zenrows queues the URLs, runs them at your plan’s concurrency, retries and stores every result for you to download. See Scrape a list of URLs.

Customize it

Troubleshooting

  • 429 with code AUTH006: more requests are in flight than your plan’s concurrency. Lower the pool size to Concurrency-Limit, and keep one pool or one SDK client for the whole run.
  • 429 right after a burst of cancelled requests: a request cancelled on your side keeps its slot until Zenrows finishes it. Keep client timeouts at 180 seconds or more so you don’t cancel work in progress.
  • Throughput is lower than expected: slow pages hold their slot longer. Use the cheapest configuration that works, for example mode=auto instead of a fixed js_render, so each request returns sooner.
  • One failure stops the whole run: an exception escaped a worker. Catch errors per URL, as the samples do, and collect failures for a retry pass.

Scrape a list of URLs

Send thousands of URLs as one Batch job.

Retry failed requests

Retry 429s and 5xx errors with backoff.

Lesson 4: Scrape every product with Batch

The Foundations lesson on moving from one URL to many.

Track usage and control spend

Keep the per-request cost low on large runs.