Shard tests across parallel jobs in GitHub Actions
Split one long test job into parallel shards with a matrix so the suite finishes in a fraction of the wall-clock time.
Do this
A test job that would run for many minutes as a single sequential run is split into N parallel shards via a matrix, each running its slice with the framework's native sharding flag (--shard for Playwright/Vitest/Jest, --partition for cargo-nextest, pytest-split for pytest). The critical path drops toward total / N plus per-job setup.123
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx playwright test --shard=${{ matrix.shard }}/4Avoid this
The whole suite runs on one runner, so the PR waits on a single long pole.
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx playwright test # every spec, one runner, one long poleWhy it matters
Sharding is a top wall-clock lever: it directly parallelizes your slowest test job. The honest tradeoff is that it trades runner-minutes for speed, the same tests still run, and each extra shard adds fixed setup overhead (checkout, install), so your bill goes up even as the critical path comes down. Stack it with dependency and build caching so per-shard setup doesn't eat the gains, and make sure your runners have enough concurrency to start every shard at once instead of queueing.
When to use
Use it when
Any test job whose wall-clock is over ~5 minutes and whose framework supports sharding.
Be careful when
When the suite is short, or when per-job setup already dominates the runtime, past a point, adding shards stops moving wall-clock because the setup tax floors it. Fix caching first, then shard.
Verify on your repo
Hand this prompt to your coding agent (Claude Code, Cursor, and the like) to audit and fix this practice in your own repo.
Inspect this repo's .github/workflows for a long test job that runs the whole suite on a single runner with no `matrix` shard axis. Identify the slowest test job (wall-clock over ~5 minutes) and confirm its framework supports sharding (`--shard` for Playwright / Jest / Vitest, `--partition` for cargo-nextest, `pytest-split` for pytest). Add a `matrix` with a `shard` axis and pass the framework's native sharding flag so the suite splits across N parallel jobs, and make sure dependency and build caching is in place so per-shard setup does not eat the gains. Show me the diff and open a PR rather than applying it blindly.Prefer to check by hand?
Identify test jobs with wall-clock over ~5 minutes.
Check whether the framework supports sharding (
--shardfor Playwright/Jest/Vitest,--partitionfor nextest,pytest-split).Confirm no
matrixshard axis is configured, a single job running the whole suite is the flag.
More best practices for GitHub Actions
Where to go next in the CI best-practices catalog.
- Parallelization
Build and test only what changed in GitHub Actions
Scope your slowest build/test job to only the packages a PR actually changed, using your monorepo tool's affected mode, with a mandatory full-run fallback so a resolution error never silently skips work.
- Caching & Setup
Cache dependencies in GitHub Actions
Cache your package manager's downloads so CI restores dependencies from a keyed cache instead of reinstalling them from scratch on every run.
FAQ
Does sharding save money or just time?
Just time. Sharding lowers wall-clock (the critical path) but raises runner-minutes, because the same test work runs across more jobs and each shard repeats setup. It's the right lever when speed matters more than the bill, pair it with caching to keep the added overhead small.
How many shards should I use?
Increase shards until the per-shard setup overhead (checkout, install, browser download) starts to dominate, that's the floor. Caching that setup lets you shard further before diminishing returns kick in.
Sources
1Playwright · test sharding (opens in new tab)
Last updated 2026-07-06
Run the suite in parallel, not in sequence.
One line to install. Faster runs on day one, and agents that open reviewable PRs to keep your pipeline following practices like this one.