News

Time-Based Sharding in Pest v4.6.0

Published
Time-Based Sharding in Pest v4.6.0 image

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

References

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Sponsored

masteringlaravel logo
Laravel Code Review

Get expert guidance in a few days with a Laravel code review

Visit Laravel Code Review

The latest

View all →
Unlearn.dev goes free for a weekend, October 10 and 11 image

Unlearn.dev goes free for a weekend, October 10 and 11

Read article
Tashil: Laravel Subscription Plans and Feature Usage Limits image

Tashil: Laravel Subscription Plans and Feature Usage Limits

Read article
Decide with Jev: Laravel AI That Answers with a Probability image

Decide with Jev: Laravel AI That Answers with a Probability

Read article
JetBrains Air: Run AI Coding Agents in JetBrains IDEs image

JetBrains Air: Run AI Coding Agents in JetBrains IDEs

Read article
Memoize Tagged Cache Reads in Laravel image

Memoize Tagged Cache Reads in Laravel

Read article
Eloquent Refreshes: Load Generated Columns After Save image

Eloquent Refreshes: Load Generated Columns After Save

Read article