Puppeteer Tracing Options Explained
Learn what Puppeteer’s tracing options control, how to capture a trace to a file or buffer, and how to inspect it in Chrome DevTools.
Puppeteer tracing records browser activity for performance diagnosis. The main options are categories (which trace events to include or exclude), path (where to write the trace), screenshots (whether to include screenshots in the trace), and bufferSize (the trace buffer size in kilobytes). Start a trace with page.tracing.start(), perform the work you want to investigate, then call page.tracing.stop(). Give start() a path to save a file; omit it to receive trace bytes from stop().
This guide follows the Puppeteer TracingOptions reference version 25.12.0 and Tracing class reference version 25.9.0. Those source pages are not version-aligned. Check the documentation for your installed Puppeteer version when exact behavior matters. TracingOptions API · Tracing class API.
1. Choose the output and capture window
Decide what question the trace should answer before capturing. For example, if a page feels slow during navigation, start immediately before navigation and stop once the page reaches the state you want to study. A trace that covers unrelated setup and cleanup can be harder to interpret.
- Choose a destination: a file path for a saved artifact, or no path if you want the returned bytes.
- Choose categories only if you need to narrow or adjust recorded events.
- Enable trace screenshots only when visual snapshots help answer the diagnostic question.
- Start, reproduce the behavior, and stop promptly.
Puppeteer documents that only one trace can be active at a time per browser. Do not start overlapping traces in pages that share a browser instance.
2. Options at a glance
| Option | Type | What it does | Documented behavior |
|---|---|---|---|
path |
string |
Writes the trace to this file path. | When omitted, the trace is not written to disk and stop() can return a Uint8Array. |
categories |
string[] |
Includes or excludes tracing categories. | Prefix a category with - to exclude it; the reference example is -toplevel. |
screenshots |
boolean |
Includes screenshots in the trace. | Defaults to false. This is separate from page.screenshot(). |
bufferSize |
number |
Sets the trace buffer size in kilobytes. | The Puppeteer 25.12.0 reference reports Chromium’s default as 200 MB (200,000 KB) when omitted or zero. Treat this as the reference’s documented default, not a guarantee for every browser build or workload. |
The options reference does not provide an exhaustive category list. Use category names appropriate to the browser tracing setup and consult the docs for the installed Puppeteer version rather than assuming an undocumented fixed set.
3. Runnable example: write a trace file
This Node.js example launches Chromium, records a navigation, saves the trace as trace.json, and closes the browser. Install Puppeteer with npm install puppeteer; run the script with node trace-file.js.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.tracing.start({
path: 'trace.json',
screenshots: false,
// categories: ['devtools.timeline', '-toplevel'],
});
try {
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
timeout: 30000,
});
} finally {
await page.tracing.stop();
}
} finally {
await browser.close();
}
})().catch(error => {
console.error(error);
process.exitCode = 1;
});
The categories line is commented out because the right categories depend on the diagnostic question. The example uses a navigation timeout as a practical bound; choose a timeout that fits the site and test environment. The finally blocks stop tracing and close the browser even if navigation fails.
4. Keep the trace bytes in memory
Omit path when you need the trace data in your program—for example, to attach it to a job result or write it to a destination chosen at runtime. stop() returns a Uint8Array according to the options reference.
const fs = require('node:fs/promises');
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.tracing.start({ screenshots: false });
let trace;
try {
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
timeout: 30000,
});
} finally {
trace = await page.tracing.stop();
}
await fs.writeFile('trace.json', Buffer.from(trace));
} finally {
await browser.close();
}
})().catch(error => {
console.error(error);
process.exitCode = 1;
});
Writing the returned bytes yourself gives you control over the output path and downstream handling. For large traces, consider whether keeping the whole result in memory fits your process limits.
5. Configure categories, screenshots, and buffer size
Categories
Pass an array of category strings through categories. A leading hyphen excludes the named category, as in '-toplevel'. Keep category selection tied to the question: broader capture may contain more detail, while narrower capture can make a particular investigation easier to inspect. The available reference does not enumerate a complete category catalog.
await page.tracing.start({
path: 'trace.json',
categories: ['devtools.timeline', '-toplevel'],
});
Screenshots
Set screenshots: true when snapshots within the trace are useful for relating visual changes to recorded activity. It defaults to false. This setting does not replace page.screenshot(), which is a separate API for saving an image.
await page.tracing.start({
path: 'trace-with-screenshots.json',
screenshots: true,
});
Buffer size
bufferSize is measured in kilobytes. The Puppeteer 25.12.0 reference reports a 200 MB (200,000 KB) Chromium default when the option is omitted or set to zero. Set an explicit value only when your capture requires it and the installed version supports the same behavior; buffer handling can depend on the browser build and workload.
await page.tracing.start({
path: 'trace.json',
bufferSize: 200000, // kilobytes; reference-documented Chromium default
});
6. Open and inspect the trace
Puppeteer’s Tracing class documentation says a trace can be opened in Chrome DevTools or a timeline viewer. In Chrome DevTools, use the Performance panel’s load option to open the saved trace. To capture traces directly in DevTools, the panel can record, save, and load performance traces.
DevTools capture settings can change the captured detail and overhead. Its documentation notes that disabling JavaScript samples can reduce overhead, while advanced paint instrumentation significantly hinders performance. When comparing runs, keep capture settings consistent and collect only the detail needed for the diagnostic question. This is practical guidance inferred from the documented setting tradeoffs, not a benchmark claim. See Chrome DevTools Performance.
The Chrome DevTools Protocol also has a lower-level Tracing domain with its own start/end methods, transfer modes, and trace configuration. Those protocol-level fields are not necessarily surfaced by Puppeteer’s higher-level TracingOptions; use Puppeteer’s own API reference for options accepted by page.tracing.start(). See the Chrome DevTools Protocol Tracing domain.
7. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No trace file appears | path was omitted, or the process cannot write to the chosen location. |
Pass a writable path, or capture the returned bytes from stop() and write them yourself. |
| No bytes are available after stopping | The trace was started with a path, so it was written to disk. | Omit path when you want stop() to return trace data. |
| Trace lacks visual snapshots | screenshots defaults to false. |
Set screenshots: true before reproducing the behavior. This affects trace contents, not page.screenshot(). |
| Trace ends before the operation completes | stop() ran too early, or navigation failed/timed out. |
Place the stop call after the operation and inspect navigation errors. Use finally to ensure tracing is stopped on failures. |
| Starting another trace fails or conflicts | Another trace is already active in the same browser. | Stop the active trace before starting another; Puppeteer documents one active trace per browser. |
| Trace is unexpectedly incomplete | The selected categories or buffer behavior may not capture what the investigation needs. | Review category selection, consider an explicit buffer size if appropriate, and check behavior against the installed Puppeteer and Chromium versions. |
| Trace seems unusually slow to collect or inspect | Extra instrumentation or screenshots can increase captured detail and overhead. | Disable unneeded trace screenshots and DevTools instrumentation. Advanced paint instrumentation is documented as significantly hindering performance. |
8. Performance, reliability, and cost considerations
- Capture only the interval you need. Short, focused traces are easier to compare and handle.
- Use consistent settings for comparisons. Category choices and DevTools instrumentation can affect the trace; changing them between runs makes comparisons less direct.
- Plan for output size and memory. A file path writes to disk; omitting it returns bytes that your application may hold in memory. Screenshots add trace content.
- Use cleanup paths. Stop the trace and close the browser in error handling so failed navigation does not leave browser resources running.
- No empirical benchmark is implied here. The documented 200 MB buffer figure is a default reported by the cited API reference, not a measured performance result.
- Tracing has no ScreenshotNeo billing relationship. Puppeteer tracing is a local browser diagnostic workflow. ScreenshotNeo is useful when the task is obtaining a website screenshot through an API rather than recording a browser performance trace.
Or skip the browser setup
If your goal is a clean website screenshot rather than a performance trace, ScreenshotNeo returns an image or PDF with one GET request. See the API documentation.
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 removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000. Sign up for free screenshots.
FAQ
Does Puppeteer tracing take a normal page screenshot?
Not by default. Trace screenshots are controlled by screenshots and default to off. Use page.screenshot() when you need a standalone image.
Can I save the trace without choosing its path in advance?
Yes. Omit path, capture the Uint8Array returned by stop(), and write it wherever your application chooses.
Can I run two traces at the same time in one browser?
Puppeteer’s Tracing class documentation says only one trace can be active at a time per browser.
Where can I view a Puppeteer trace?
Open the trace in Chrome DevTools or a timeline viewer. The Tracing class documentation names both options.


