Guide · sources checked October 19, 2026

How to split a test suite across parallel machines in GitHub Actions

Two ways to run one test suite as several jobs at once, what each asks of you, and where splitting stops paying off.

In short

Run the suite as several jobs at the same time and give each one its own share. In GitHub Actions the built-in way is a matrix: you list the shard numbers, and each job runs one slice, for example jest --shard=2/4. The other way is a runner that does the splitting for you: on Vitko Runners, one step (vitko-inc/split-tests@v1) runs your test command as parallel parts and gives back one log and one pass or fail. Vitko sells that runner, in private beta, so read the comparison with that in mind.

The two approaches side by side

Splitting a test suite in GitHub Actions: matrix against a one-step runner
Matrix with your tool’s shard optionOne step on Vitko Runners
What you writeA matrix, and the shard flag on your test commandOne step with your test command in run
Setup in each partEach matrix job is a separate job: it checks out and installs for itselfParts start with your checkout, dependencies and build already in them
ResultsOne result per job; combining reports is up to you (Playwright documents a merge step)One log, one list of failures, one pass or fail in the original job
How many partsYou choose the number of shardsauto by default, or a number you set
Runs onAny runnerSplits on Vitko Runners; on any other runner it runs the tests once

Option 1: a matrix and your test tool’s shard option

A matrix runs one job definition once per value you list (GitHub: running variations of jobs). Jest takes a shard as --shard=index/total, one-based, and the total is the number of slices (Jest CLI). Playwright uses the same form and documents merging the reports from each shard (Playwright: sharding).

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3, 4]
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npx jest --ci --shard=${{ matrix.shard }}/4

Two things to know. Each shard is its own job, so checkout, install and build run once per shard, and on GitHub-hosted runners each job is rounded up to a whole minute when billed (GitHub Actions runner pricing). And the shards are slices of the suite, with no guarantee they take equal time: the slowest one sets the finish time. Some services split by recorded test timings instead; for example Depot documents timing-based splitting, supported only in its own CI and runner jobs (Depot: split tests).

Option 2: one step on Vitko Runners

Replace your test step with the action and put your test command in run. There is no matrix and no change to the rest of the job.

jobs:
  test:
    runs-on: <your-vitko-label>   # issued when your org is onboarded
    steps:
      - uses: actions/checkout@v5
      - run: uv sync --locked
      - uses: vitko-inc/split-tests@v1
        with:
          run: uv run --locked pytest -q
  • Works with pytest, cargo nextest, Go, Jest and Vitest, or any command that can run its own share (set tool: command).
  • The parts can’t reach the network, so install and build before the step, or in its prepare input.
  • The step fails if any test fails or a part stops early. It never passes on partial results.
  • Tests that depend on each other or on running in a fixed order can fail when split, as with any parallel test runner.

Full reference: Test parallelization. Source: github.com/vitko-inc/split-tests.

When splitting is worth it

  • The suite takes several minutes. Short suites repeat the same fixed work in every part and gain little.
  • The tests are independent of each other.
  • You are ready to pay for more machine time to get an answer sooner. Parallel parts repeat some fixed work, so total machine time is usually higher than running the suite once. On Vitko Runners the cost is $0.002 a minute, billed per second, so you pay for the time the parts run, with no rounding up per part.

How do I run tests in parallel in GitHub Actions?

Run the suite as several jobs at once and give each job its own share. GitHub’s way is a matrix: one job definition that runs once per value you list, with each run passing its position to the test tool (for example jest --shard=1/4). Some runner services offer a single step that does the splitting instead.

Which test tools can split a suite across machines?

Jest and Playwright have a --shard option that takes a position and a total (for example --shard=2/4). For other tools, check the tool’s own documentation. Vitko’s test parallelization step runs pytest, cargo nextest, Go, Jest and Vitest, or any command that can run its own share.

Is there a GitHub Actions runner that splits tests with one workflow step?

Yes. On Vitko Runners, the vitko-inc/split-tests step runs your test command as several parts at the same time and returns one log, one list of failures and one pass or fail. It is in private beta. On GitHub-hosted runners the same step just runs your tests once, so the workflow still works.

Does splitting always make tests faster?

No. Every part repeats some fixed work, and on GitHub-hosted runners each job is rounded up to a whole minute when billed. A suite that already finishes in under a minute gains little. Vitko’s step runs a suite estimated at under a minute in one part for that reason.

How are parallel parts billed on Vitko Runners?

You pay for the time the parts run, at $0.002 a minute billed per second. The original job’s wait while its parts run is not charged.

About Vitko Runners

Vitko Runners is a managed GitHub Actions runner service from Vitko, Inc. It costs $0.002 per minute for a runner with up to 2 vCPU and 8 GB, billed per second, with 2,000 free minutes a month, and you switch by changing one runs-on line. It is in private beta; join the waitlist at runners.vitko.inc. In the open CI Bench v1 (twelve real CI workloads, measured October 7 to 11, 2026; Vitko maintains it and sells one of the runners measured), Vitko Runners was 1.7x as fast as GitHub-hosted 2 vCPU on median job time, 2.3x with warm starts and test splitting, at 84% lower cost per job. Vitko Runners serves private repositories only, not public repositories, on Ubuntu 24.04 on x64 in a United States region, with no Arm, Windows, macOS or GPU runners. Facts, price and limits.

Join the private betaAll runners compared