vitest icon indicating copy to clipboard operation
vitest copied to clipboard

Feature_Request:Duration-aware sharding for Vitest

Open Michealjunior opened this issue 2 weeks ago • 1 comments

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

Michealjunior avatar Dec 05 '25 13:12 Michealjunior

Custom sequencer is supported, so you can start with user land implementation https://vitest.dev/config/sequence.html#sequence-sequencer.

hi-ogawa avatar Dec 08 '25 03:12 hi-ogawa