-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Clear and concise description of the problem
As a developer using Vitest, I want an opt-in sharding mode that distributes test files based on historical execution time, so that shards finish at roughly the same time and no single slow shard blocks the overall CI run.
Vitest’s current approach uses a simple file-count distribution, which does not account for slow or heavy test files. In large codebases, this often leads to uneven shard durations and unnecessary waiting time in CI.
I am willing to contribute a PR for this feature.
Suggested solution
We could provide the following implementation:
Introduce a boolean config option:
test: {
sequence: {
balanceShardsByTime: false
}
}
Default remains false to avoid breaking existing behavior.
When balanceShardsByTime is enabled:
Vitest reads a persisted per-file execution-time history (e.g., .vitest-timing.json).
Files are sorted by expected runtime (descending).
A greedy bin-packing algorithm assigns files into shards to achieve roughly equal total expected duration.
If a file has no historical timing:
Treat it with a fallback weight (e.g., average or minimal cost) to avoid distortion.
Assignment remains deterministic for the same inputs & timing data.
When disabled or when no timing history exists, Vitest must:
Fall back to the existing count-based sharding, ensuring full backward compatibility.
Additional requirements:
Must not break or regress:
watch mode
filtering (e.g., --run, test name filters)
custom sequencers
Must tolerate corrupted or partially missing timing data.
Alternative
A plugin-based timing collector — rejected because timing data is already available from previous Vitest runs, and core support provides better consistency.
Hash-based deterministic randomization — improves distribution only slightly and does not solve slow-file bottlenecks.
Per-test (not per-file) timing — more accurate but far more complex and unnecessary for the first implementation phase.
Additional context
This feature is common in large CI environments where dozens or hundreds of test files exist. Frameworks like Jest and Bazel offer similar duration-aware balancing options.
Adding this to Vitest would meaningfully improve CI throughput and developer experience while remaining strictly opt-in and non-breaking.
If needed, I can also provide:
a draft JSON schema for timing persistence
suggested file format
a prototype shard balancing algorithm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.