Pest v4.6.0 adds time-based shard distribution, a new mode that balances CI shards by actual test execution time rather than file count. If you're already using --shard in CI, recording timing data with --update-shards and committing the resulting JSON file is all that's needed to switch those jobs to time-balanced distribution.
- Time-based shard distribution via
--update-shards - Timing data stored in
tests/.pest/shards.json
What's New
Time-Based Sharding
When running tests in parallel across multiple CI shards, splitting by file count can produce uneven jobs — one shard finishes in seconds while another takes several minutes. Pest v4.6.0 addresses this with time-balanced sharding.
Step 1: Run the full test suite with --update-shards to record per-class timing data:
./vendor/bin/pest --update-shards
You can combine this with --parallel to speed up the timing run:
./vendor/bin/pest --parallel --update-shards
This writes each test class's duration to tests/.pest/shards.json:
{ "timings": { "Tests\\Feature\\Payments\\StripeCheckoutTest": 1.608, "Tests\\Feature\\Reports\\SalesReportTest": 2.105, "Tests\\Unit\\Models\\UserTest": 0.050 }, "checksum": "...", "updated_at": "2026-04-14T10:30:00+00:00"}
Step 2: Commit tests/.pest/shards.json to your repository.
Step 3: Run sharded CI jobs as usual. When the timing file is present, Pest automatically uses time-balanced distribution:
./vendor/bin/pest --shard=1/5
The output confirms time-balanced sharding is active:
Shard: 1 of 5 — 12 files ran, out of 50 (time-balanced).
When test files are added or renamed after the timing file was last generated, Pest detects the staleness and displays a warning:
WARN The [tests/.pest/shards.json] file is out of date...
Tests still run: new files are distributed evenly across shards while known files remain time-balanced. Deleting test files does not trigger the warning, and stale timing entries are ignored until you regenerate the file.
A GitHub Actions matrix setup looks like this:
strategy: matrix: shard: [1, 2, 3, 4, 5] steps: - name: Run tests run: ./vendor/bin/pest --shard=${{ matrix.shard }}/5
PR: #1671, contributed by @nunomaduro