Use one Puppeteer browser, give each URL its own page, and cap how many pages run at once. This Node.js example captures a list of URLs concurrently, writes uniquely named PNG files, reports individual failures, and closes the browser even if a capture fails.
How parallel screenshots work in Puppeteer
Puppeteer’s screenshot guide puts the capture on a page: “For capturing screenshots use Page.screenshot().” A browser can hold multiple pages, so each screenshot job can use its own page while sharing one browser process. Do not reuse a page for independent URLs: concurrent navigations on the same page can interfere with each other.
Parallel means several jobs are in progress at the same time; it does not mean launching every URL at once. Puppeteer’s documentation does not prescribe a concurrency limit or publish a throughput benchmark. Choose a small worker limit, then measure it on your machine and target sites. Puppeteer Screenshots guide · Page class API
Requirements and setup
The Puppeteer system requirements page reviewed for this guide specifies Node.js 22.12 or later. Requirements can change; check the page when choosing an installed Puppeteer release. The examples use the Puppeteer API documented for version 25.12.0 in the source pages reviewed on October 3, 2026.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
- 14" diagonal, 1366x768 resolution, HD BrightView LED, Glossy NON-TOUCH Display
- Install a supported Node.js version.
- Create a project and install Puppeteer:
npm init -y, thennpm install puppeteer. - Save the script below as
screenshots.mjs. The.mjsextension enables the shown ES module import without changing project configuration. - Replace the sample URLs with pages you are allowed to access, then run
node screenshots.mjs.
Puppeteer’s package manages a compatible browser for its standard setup. If you use a separately installed browser or a different Puppeteer package, follow that setup’s browser configuration requirements. Puppeteer system requirements
Runnable script: bounded parallel captures
This implementation launches one browser and starts a fixed number of workers. Each worker creates its own page for a URL, saves a PNG, and closes that page. A failed URL is reported without preventing the other workers from attempting their jobs; the script exits with a nonzero status if any capture failed.
Rank #2
- 1.1 GHz (boost up to 2.4GHz) Intel Celeron N5030 Quad-Core
- 4GB DDR4 System Memory; 128GB Solid State Drive
- 11.6" HD (1366 x 768) Multi-Touch Display
- Combo headphone/microphone jack - Noble Wedge Lock slot - HDMI; 2 USB 3.1 Gen 1
- Windows 11 Pro
import puppeteer from 'puppeteer';
import { mkdir } from 'node:fs/promises';
const urls = [
'https://example.com',
'https://www.wikipedia.org',
'https://nodejs.org',
];
const outputDir = 'screenshots';
const concurrency = 3; // Operational choice; tune for your workload.
function filenameFor(index, url) {
const host = new URL(url).hostname.replace(/[^a-z0-9.-]/gi, '_');
return `${String(index + 1).padStart(3, '0')}-${host}.png`;
}
async function main() {
await mkdir(outputDir, { recursive: true });
const browser = await puppeteer.launch();
const failures = [];
let nextIndex = 0;
async function worker() {
while (true) {
const index = nextIndex++;
if (index >= urls.length) return;
const url = urls[index];
let page;
try {
page = await browser.newPage();
await page.setViewport({ width: 1365, height: 900 });
await page.goto(url, {
waitUntil: 'networkidle2',
timeout: 45_000,
});
const path = `${outputDir}/${filenameFor(index, url)}`;
await page.screenshot({ path, type: 'png', fullPage: false });
console.log(`Saved ${url} -> ${path}`);
} catch (error) {
failures.push({ url, message: error instanceof Error ? error.message : String(error) });
console.error(`Failed ${url}: ${failures.at(-1).message}`);
} finally {
if (page) await page.close().catch(() => {});
}
}
}
try {
const workerCount = Math.min(concurrency, urls.length);
await Promise.all(Array.from({ length: workerCount }, () => worker()));
} finally {
await browser.close();
}
if (failures.length) {
console.error(`${failures.length} of ${urls.length} screenshot(s) failed.`);
process.exitCode = 1;
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
For details on screenshot return data, screenshot lifecycle behavior, and supported options, see Page.screenshot() and the ScreenshotOptions interface.
What the worker pool is doing
nextIndexassigns each URL once. JavaScript runs this increment synchronously before the worker reaches its next await, so workers do not claim the same index.Math.min(concurrency, urls.length)avoids creating idle workers when the list is short. An empty list creates no workers and still closes the browser.- Every job uses its own page, but all pages share one browser. The worker limit bounds simultaneously active pages rather than the total number of URLs.
- The index plus hostname makes output names distinct even if the input contains the same host more than once. If your input may contain duplicate URLs, the index still prevents overwrites.
networkidle2is a navigation wait condition, not a guarantee that every page’s content is complete. Sites with long-running connections or delayed rendering may need a different wait strategy.
Adjusting the screenshot
The example captures the viewport at 1365 × 900 and explicitly writes PNGs. Set a page’s viewport before navigating when you need consistent responsive rendering; this example does so. Puppeteer’s screenshot options include these commonly useful controls:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteRank #3
- 256 GB SSD of storage.
- Multitasking is easy with 16GB of RAM
- Equipped with a blazing fast Core i5 2.00 GHz processor.
| Need | Option | Behavior |
|---|---|---|
| Capture the page beyond the viewport | fullPage: true |
Captures the full page rather than only the visible viewport. |
| Capture a region | clip |
Limits the capture to a specified rectangle. |
| Choose a destination | path |
Saves the image to a file. When the type is not specified, the file extension determines the screenshot type. |
| Choose an image format | type |
Selects an image type such as PNG, JPEG, or WebP, subject to the installed version’s supported options. |
| Adjust lossy image quality | quality |
Applies to lossy formats, not PNG. |
| Keep a transparent background | omitBackground: true |
Omits the default background where the page and output format allow transparency. |
Check the installed version’s API reference for exact option types and defaults. Full-page images can be substantially larger than viewport captures, so consider the target dimensions, file size, and memory use when choosing both capture mode and concurrency.
Choosing concurrency and output strategy
How many pages should run at once?
There is no documented universal page limit for this task. Start with a modest worker count and observe completion time, memory use, browser stability, and any rate limiting or blocking by target sites. Increase the limit only while those remain acceptable. A browser page consumes resources, and large full-page captures or heavy sites may make a limit that works for simple pages unsuitable.
Rank #4
- EFFORTLESS EVERYDAY PERFORMANCE: Powered by Intel Celeron N4020 processor and Windows 11 Home system, delivering reliable, low-power efficiency for daily tasks like document editing, email, online classes, and web browsing
- 15.6-INCH FULL HD DISPLAY: Enjoy immersive visuals on the 15.6" FHD (1920x1080) anti-glare screen with micro-edge bezels. Delivers clear details and comfortable viewing for long study sessions, working on spreadsheets, and video playback
- RESPONSIVE MULTITASKING & STORAGE: Built with 4GB LPDDR4 RAM and 128GB eMMC storage for smooth daily essential use. Expand your storage by up to 1TB via the integrated TF card slot to easily store movies, photos, and working files
- ADVANCED CONNECTIVITY: Outfitted with 2x Full-Featured Type-C ports for data transfer, fast charging, and dual-monitor output, alongside 2x USB 3.2 Gen1 ports and a 3.5mm audio jack for complete peripheral compatibility
- LIGHTWEIGHT & SILENT OPERATION: Slim and portable for effortless travel or commuting. Features a 1MP HD webcam for remote meetings, 38Wh battery with 45W Type-C fast charging, and a fanless silent design for peaceful work environments.
Use one browser with multiple pages as shown when you want to avoid launching a separate browser process for every URL. Separate browser processes may provide stronger process isolation, but require managing more browser instances; the official pages cited here do not publish performance comparisons between these choices. Benchmark your own workload rather than treating either as universally faster.
When Promise.all is enough
For a short, known-small list, creating one page per URL and awaiting Promise.all is straightforward. It starts all jobs together, however, so it is not a safe default for an arbitrarily large list. The worker-pool pattern limits the number in flight without requiring a separate dependency.
Recommended Free Tools
Best Value
- WINDOWS 11 | STABLE PERFORMANCE: Powered by Intel Celeron N4020 processor and Windows 11 system, this laptop delivers stable performance for everyday computing tasks. It supports web browsing, online learning, document editing, email communication, and basic office work with optimized power efficiency, providing a practical and reliable experience for essential daily use for daily use.
- 15.6” FHD IPS DISPLAY: Features a 15.6-inch Full HD IPS display with narrow bezels, offering wider viewing angles and clearer image details compared to standard panels. The improved screen-to-body ratio enhances visual experience for study, reading, document work, and video playback, making it suitable for both productivity and entertainment use.
- 4GB DDR4 + 128GB eMMC STORAGE: Equipped with 4GB DDR4 memory and 128GB eMMC storage for everyday basics such as browsing, documents, email, and online learning platforms. The built-in TF card slot supports storage expansion up to 1TB, giving you more flexibility for files, photos, videos, and daily documents. TF card not included.
- CONNECTIVITY & PORTS: Includes 1× TF card slot, 2× USB 3.2 Gen1 ports, and 2× full-featured Type-C ports (USB 3.2 Gen1). The Type-C ports support data transfer, charging, and video output, enabling flexible connection with external devices such as monitors, storage, and peripherals for daily work and study use.
- LIGHTWEIGHT DESIGN | ONLINE COMMUNICATION: Designed with a slim, portable profile, this laptop is easy to carry for school, commuting, and travel. A built-in 1MP front camera supports online classes, video meetings, remote communication, and everyday conferencing. The 3300mAh battery works with the low-power system design to support practical daily use, while thermal optimization helps maintain quieter operation during extended tasks.
Files or in-memory data
The example supplies path, so each capture is saved directly to disk. Puppeteer’s screenshot method also resolves with image data, which is useful if the next step is processing or uploading the image instead of keeping a local file. If using memory output, avoid retaining many large image buffers at once; consume or write each result as soon as it is available.
Common errors and fixes
- Node.js version or install errors: Check the installed Node version against Puppeteer’s current system requirements, then reinstall dependencies with that supported runtime.
- Browser fails to launch: Confirm Puppeteer installed its browser successfully and that the runtime environment permits launching it. If configuring a browser executable yourself, verify its path and compatibility with the installed Puppeteer version.
- Navigation timeout: The site may be slow, unreachable, or never reach the selected network-idle condition. Check the URL and connectivity; choose a suitable timeout or wait condition, or wait for a specific page element when the page’s readiness is defined by that element.
- Screenshot is blank or incomplete: Navigation completion does not necessarily mean client-rendered content or lazy-loaded assets are ready. Wait for the relevant selector or application state before calling
screenshot(). - Files overwrite each other: Ensure each job gets a unique path. The sample includes the list index for this reason; a hostname alone is insufficient when multiple URLs share a host.
- Browser closes unexpectedly or resource use spikes: Reduce
concurrency, especially for full-page captures and resource-heavy sites. The limit is a workload choice, not an official Puppeteer recommendation. - One failure appears to stop the whole batch: Keep errors inside each worker, as in the sample, rather than allowing one rejected capture promise to bypass cleanup. The outer
finallyensures the shared browser is closed.
Or skip the browser setup
ScreenshotNeo is a screenshot API and MCP server for developers. A single GET request can return an image or PDF. For a batch, make one request per URL with your own bounded Node.js worker pool; the API also supports bulk capture of up to 100 URLs per call. See the ScreenshotNeo API documentation for request options.
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 before capture and more than 60 known consent platforms, newsletter popups, and chat widgets are removed; each step can be turned off.
- Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers indicate the page verdict and whether the request was billed.
- An MCP server offers
take_screenshot,get_page_info, andcapture_pdftools for Claude, Cursor, and other MCP clients. - The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan.
Sign up for 1,000 free screenshots a month, with no card.
Frequently Asked Questions
Does Puppeteer set a recommended concurrency limit for screenshot jobs?
No. Its cited documentation does not specify a maximum or recommended number of simultaneous pages; choose and measure a limit for your workload.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteCan I use one Puppeteer page for several URLs at once?
Not for independent concurrent captures. Give each active URL its own Page so navigations and screenshots do not conflict.
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.

