Skip to main content

When Playwright outgrows your GitHub Actions runner

· 7 min read
Playrunner
Playrunner contributors

GitHub Actions is a great place to run Playwright tests. For small and medium suites, a standard hosted runner may be all you need.

But browser testing is a compute-heavy workload. As suites grow, teams can reach a point where adding more tests or more Playwright workers does not make CI faster. It can make it slower, less predictable, and sometimes more flaky.

The problem is not GitHub Actions or Playwright. It is the amount of compute available to the workload.

Why Playwright can become expensive to run

A Playwright worker is not a lightweight unit of work. Depending on the suite, a CI job may be running several browser processes alongside Node.js, the application under test, service containers, network proxies, reporters, trace collection, screenshots, and video recording.

Increasing Playwright's worker count increases the amount of work competing for the same CPU and memory.

That is why Playwright's own CI guidance recommends using a single worker in resource-constrained CI environments for stability and reproducibility, while using sharding across multiple CI jobs when wider parallelism is needed.

See the Playwright CI documentation and Playwright sharding documentation for the underlying recommendations.

A typical setup might begin like this:

GitHub Action


GitHub-hosted runner


400 Playwright tests

├── browser processes
├── application processes
├── traces and screenshots
├── CPU contention
└── memory pressure

When the runner is comfortably within its limits, this works well. When it is not, the symptoms are familiar: longer test times, navigation timeouts, browser processes competing for resources, and tests that are stable locally becoming less reliable in CI.

A standard runner is still a finite machine

For private repositories, GitHub currently documents the standard ubuntu-latest hosted runner as a 2 CPU, 8 GB RAM virtual machine. GitHub also offers larger hosted runners, including Linux machines with substantially more CPU and memory.

See GitHub-hosted runners and the larger runners reference for current specifications.

Moving to a larger runner is one solution. But there is another dimension to the problem: horizontal scaling.

Instead of asking one increasingly large machine to execute the entire suite, you can divide the suite across multiple machines.

Shard the workload instead of fighting the machine

Playwright supports this directly with --shard:

npx playwright test --shard=1/4
npx playwright test --shard=2/4
npx playwright test --shard=3/4
npx playwright test --shard=4/4

Each shard can run independently on a different machine.

Conceptually, a 400-test suite could become:

400 tests

┌───────────┼───────────┐
│ │ │
▼ ▼ ▼ ▼
Runner 1 Runner 2 Runner 3 Runner 4
~100 tests ~100 tests ~100 tests ~100 tests

GitHub Actions can do this with a matrix strategy, and Playwright documents this approach explicitly.

It is a good solution, but it also moves infrastructure decisions into your CI configuration. The team now needs to decide how many shards to create, how much compute each shard should receive, how reports should be merged, and whether that topology still makes sense as the suite grows.

A 50-test smoke suite and a 4,000-test regression suite have very different compute requirements.

That is the problem behind Playrunner's elastic execution roadmap.

Let GitHub trigger the test workload, not necessarily host it

GitHub Actions is excellent at answering when a test workflow should run:

  • a pull request was opened;
  • code was merged to main;
  • a release is being prepared;
  • a deployment is about to happen.

It does not mean all browser compute has to execute inside the same GitHub runner.

Playrunner is being built to own that execution workflow end to end. GitHub will remain the CI trigger and quality gate, while Playrunner automatically decides how to run the Playwright workload:

GitHub Actions

│ trigger workflow

Playrunner

│ discover suite and choose topology
├────────┬────────┬────────┬────────┐
▼ ▼ ▼ ▼ ▼
Shard 1 Shard 2 Shard 3 Shard 4 Shard 5
│ │ │ │ │
└────────┴────────┴────────┴────────┘


Merge reports and artifacts


Combined test result


GitHub Actions
pass / fail

The pipeline keeps one simple responsibility: start the workflow and react to its result. It does not need a shard matrix, runner provisioning logic, or a report-merging job.

Playrunner will inspect the workload, choose an execution topology, provision the runners, distribute the tests, merge their reports and artifacts, and return one result. As the suite changes, Playrunner will be able to change that topology without requiring a rewrite of the GitHub Actions workflow.

Today, GitHub Actions can already trigger a Playrunner workflow and receive its result. Playrunner can execute that workflow on a local runner, user-managed GCP infrastructure, or Playrunner Cloud, and manually modelled sibling branches can run in parallel. Automatic suite discovery, sharding, and report merging are the next capabilities on the roadmap, tracked in suite sharding, report merging, and elastic planning.

Run the compute where it makes sense

The CI provider that triggers a Playrunner workflow should not determine where the browser workload runs. Playrunner's execution-target model is intended to place each part of a workflow on the compute that fits it best.

That opens up several useful patterns:

  • trigger a test from GitHub Actions but run it on AWS;
  • run high-memory browser workloads on GCP;
  • run near Azure-hosted applications and services;
  • use infrastructure inside your own network for protected environments;
  • keep specialist self-hosted hardware available for particular test suites;
  • combine cloud and local execution in one broader test workflow.

This separation becomes increasingly useful as test suites grow because CI and compute stop being the same decision.

Today, Playrunner supports local, user-managed GCP, and hosted GCP execution. CPU, memory, and Playwright worker settings can be configured for a Playwright node, while runner selection currently applies to the workflow as a whole. AWS, Azure, and mixed per-node execution targets are planned in the AWS runner issue, the Azure runner issue, and the per-node execution-target issue.

The next step: elastic Playwright compute

Sharding is useful, but a fixed shard count is still a static decision.

Imagine a workflow where the execution platform can look at the workload before it starts:

Suite discovered: 2,400 tests
Historical duration: 3h 12m
Requested target: ~10 minutes
Available runner size: 4 vCPU



choose execution topology


provision runners


distribute tests


execute in parallel


merge test results


return one pass/fail result

The important change is that the developer should not have to think in terms of "how many GitHub matrix entries should this suite have?"

They should be able to describe the outcome they need and let the execution platform decide how to achieve it.

That is where we see Playrunner heading: not just orchestrating tests, but making elastic compute for Playwright a normal part of the testing workflow.

Roadmap status at the time of writing

As of August 10, 2026, the elastic execution model above is a roadmap, not a description of the current product. We have opened the following implementation issues so progress and design decisions are visible:

Until those issues are implemented, teams that need suite-level sharding must configure Playwright shards and report merging themselves, or manually model independent test branches as separate Playrunner nodes.

If you want to use Playrunner as a GitHub Actions quality gate today, see Use Playrunner as a CI/CD quality gate.