Skip to content
Latchkey

How to Split Tests by Timing with GitHub Actions

Splitting by recorded timing keeps every shard roughly equal in duration, so no single runner becomes the bottleneck.

Sharding by file count leaves uneven shards when a few tests dominate runtime. Tools like Playwright with timing data, or split-tests style utilities, partition by measured duration so shards finish together.

Steps

  • Record per-test timings on a baseline run (most runners emit a JSON report).
  • Feed those timings to a splitter that partitions tests into equal-duration groups.
  • Run each group on a separate shard in the matrix.

Workflow

.github/workflows/ci.yml
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3]
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      # Playwright reads its own timing data to balance shards
      - run: npx playwright test --shard=${{ matrix.shard }}/3

Gotchas

  • Timing data drifts as tests change; refresh it periodically or shards drift out of balance.
  • A new long test landing between refreshes can briefly unbalance one shard.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →