Skip to content

Create shard based on test run time#1668

Closed
vistik wants to merge 1 commit intopestphp:4.xfrom
vistik:exp/time-based-sharding
Closed

Create shard based on test run time#1668
vistik wants to merge 1 commit intopestphp:4.xfrom
vistik:exp/time-based-sharding

Conversation

@vistik
Copy link
Copy Markdown

@vistik vistik commented Apr 13, 2026

What:

  • Bug Fix
  • New Feature

Description:

Time-based test sharding

Adds a --shard-timing option that enables time-balanced sharding when combined with the existing --shard flag. Instead of splitting tests by count (which can create unbalanced CI runners when some test classes are much slower than others), this distributes test classes across shards to minimize the overall wall-clock time of a parallel run.

How it works

Pass a path to a timing file alongside --shard:

./vendor/bin/pest --shard=1/4 --shard-timing=junit.xml

The plugin resolves timing data from two sources, in order of preference:

  1. JUnit XML — parses time attributes (falls back to elements if no suite-level class attributes are present)
  2. PHPUnit result cache — reads test-results or .phpunit.result.cache from the configured or default cache directory

Tests are then distributed using the LPT (Longest Processing Time) bin-packing algorithm: classes are sorted slowest-first, and each is assigned to the shard with the lowest accumulated time so far. This greedy approach minimizes the maximum shard duration with no extra configuration.

When no timing file is available (first run, file missing), it falls back to the existing even-count split. Unknown test classes default to 1 second estimated runtime.

The catch

For this to work really you need to commit your junit.xml file to your repo, and keep it up to date with new added test 😄

@0x15f
Copy link
Copy Markdown

0x15f commented Apr 14, 2026

Love this 🙏

@nunomaduro
Copy link
Copy Markdown
Member

Thanks! It was a good starting point, going to ship it here: #1671

@nunomaduro nunomaduro closed this Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants