Skip to content
Latchkey

How to Balance Test Shards Evenly in CI

Splitting by file count leaves one slow shard as a straggler; splitting by duration keeps every shard finishing together.

Collect per-test durations, sort descending, and greedily place each test on the shard with the smallest running total (longest-processing-time-first).

Steps

  • Record durations from a recent green run (JUnit or a runner timings file).
  • Sort tests longest first.
  • Assign each test to the currently lightest shard.

Terminal

Terminal
# LPT packing sketch: assign heaviest tests to the lightest shard
python - <<'PY'
tests = sorted(load_durations(), key=lambda t: -t.seconds)
shards = [[] for _ in range(3)]
totals = [0, 0, 0]
for t in tests:
    i = totals.index(min(totals))
    shards[i].append(t.name)
    totals[i] += t.seconds
print(totals)
PY

Gotchas

  • Balance is only as good as the timing data; refresh it as the suite grows.
  • Fixed-size matrix shards cannot rebalance mid-run; use queue mode for that.

Related guides

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