Heuristic:Microsoft Playwright Timeout Configuration Tips
| Knowledge Sources | |
|---|---|
| Domains | Testing, Debugging |
| Last Updated | 2026-02-11 22:00 GMT |
Overview
Timeout configuration strategy covering Playwright's four-tier timeout hierarchy, debug mode auto-disabling, and the Node.js +1ms compensation workaround.
Description
Playwright uses a layered timeout system with distinct defaults for different operation types: general actions (30s), expect assertions (5s), browser launch (3min), and navigation (30s). Timeouts cascade through a parent-child hierarchy (Playwright → Browser → Context → Page), where each level can override the parent. A critical implementation detail is the +1ms compensation for a known Node.js bug where `setTimeout` can fire slightly early. Additionally, debug mode (`PWDEBUG`) disables all timeouts by returning 0, preventing debugger breakpoints from being interrupted.
Usage
Use these tips when configuring test timeouts, debugging flaky tests that fail intermittently near timeout boundaries, or setting up a debug workflow with breakpoints.
The Insight (Rule of Thumb)
- Action: Understand the four default timeout values and configure them appropriately for your test suite.
- General action timeout: 30 seconds (`DEFAULT_PLAYWRIGHT_TIMEOUT`)
- Expect assertion timeout: 5 seconds (`defaultExpectTimeout`)
- Browser launch timeout: 3 minutes (`DEFAULT_PLAYWRIGHT_LAUNCH_TIMEOUT`)
- Network timeout: 30 seconds (`NET_DEFAULT_TIMEOUT`)
- Action: Use `PWDEBUG=1` to automatically disable all timeouts when debugging with breakpoints.
- Action: Be aware that Playwright adds +1ms to all timer deadlines to compensate for Node.js issue #26578.
- Trade-off: Setting timeouts too low causes flaky tests; setting them too high slows down failure detection.
- Trade-off: The `test.slow()` helper multiplies the test timeout by 3x, which is useful for resource-intensive tests but should not be the default.
Reasoning
The timeout hierarchy exists because different operations have fundamentally different expected durations. Browser launching involves process creation and IPC negotiation (hence 3 minutes), while DOM assertions should resolve within a few seconds via auto-retrying. The +1ms Node.js workaround addresses a real platform bug where `setTimeout(fn, X)` can fire at `X - 0.5ms`, causing premature timeout errors. Debug mode disabling is essential because breakpoints pause JavaScript execution but not timers, which would otherwise kill the session during debugging.
The cascade design (Playwright → Browser → Context → Page) allows fine-grained control: set a global default, then override per-context for specific test scenarios. The expect timeout is deliberately shorter (5s vs 30s) because assertions that take longer than 5 seconds usually indicate a test design problem rather than normal latency.
Code Evidence
Default timeout constants from `packages/playwright-core/src/utils/isomorphic/time.ts:39-40`:
export const DEFAULT_PLAYWRIGHT_TIMEOUT = 30_000;
export const DEFAULT_PLAYWRIGHT_LAUNCH_TIMEOUT = 3 * 60 * 1000; // 3 minutes
Default expect timeout from `packages/playwright/src/matchers/expect.ts:181`:
const defaultExpectTimeout = 5000;
Node.js +1ms compensation from `packages/playwright/src/worker/timeoutManager.ts:124-127`:
// Compensate for Node.js troubles with timeouts that can fire too early.
// We add an extra millisecond which seems to be enough.
// See https://github.com/nodejs/node/issues/26578.
const timeout = running.deadline - monotonicTime() + 1;
Debug mode timeout disabling from `packages/playwright-core/src/client/timeoutSettings.ts:54-55,66-67,78-79`:
// In navigationTimeout():
if (this._platform.isDebugMode())
return 0;
// In timeout():
if (this._platform.isDebugMode())
return 0;
// In launchTimeout():
if (this._platform.isDebugMode())
return 0;
The `test.slow()` multiplier from `packages/playwright/src/worker/timeoutManager.ts:138-142`:
slow() {
const slot = this._running ? this._running.slot : this._defaultSlot;
slot.timeout = slot.timeout * 3;
}