Skip to content

feat: add browser pool pre-warming to run-server #39499

@paddymul

Description

@paddymul

Problem

When using playwright run-server with multiple test workers, all workers launch their browsers at roughly the same time. Each browser launch costs 2-5s of heavy CPU, so N workers starting simultaneously creates a sharp CPU spike followed by idle time — the load profile is spiky rather than saturated.

This pattern repeats whenever workers cycle (e.g. between test files): a burst of concurrent browser launches, then relative quiet. The CPU is either pegged or underutilized, never steadily loaded.

Proposal

Add --pre-warm <count> and --browser <browser> options to run-server. When specified:

  1. The server launches N browsers into a pool before accepting connections
  2. Incoming WebSocket clients receive an already-running browser instantly (no launch wait)
  3. After handing out a browser, the server replenishes one at a time in the background

This smooths the CPU profile: instead of N simultaneous browser launches causing a spike, launches are spread out — one replenishment at a time, overlapping with actual test execution. The CPU stays steadily loaded rather than alternating between spikes and idle.

Usage

# Pre-warm 4 browsers before accepting connections
npx playwright run-server --port 3333 --pre-warm 4 &

# Workers get instant browsers, replenishment happens in background
PW_TEST_CONNECT_WS_ENDPOINT=ws://localhost:3333/ npx playwright test

Behavior

  • Pool browsers handed out FIFO to connecting workers
  • Background replenishment after each handout (one at a time, not all at once)
  • Falls back to standard on-demand launch when pool is empty or client requests a socks proxy
  • --pre-warm 0 or omitting the flag = current behavior, no change to default path

Motivation

We run a CI setup where a single run-server instance serves multiple test workers on the same machine. The goal is to keep CPU utilization high and steady rather than spiky. Pre-warming + serial replenishment achieves this by decoupling browser startup from test worker connection timing.

I have a working implementation and can open a PR if there's interest.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions