Skip to main content
Status: Active Owner: Platform Architecture Phase: 1.D of docs/recommendations/DEV_VELOCITY_AND_ARCHITECTURE_PLAN_2026-04-22.md The unit-test suite is 1,657 test files / ~7,167 tests as of 2026-04-22, with a wall-clock cost of ~3 m 43 s unsharded (per reports/perf/baseline-2026-04-22.md). Vitest already runs files in parallel within a single process (pool: 'threads', maxWorkers: '50%' in CI — see vitest.config.ts), but a single CI runner still pays the full ~4-minute wall-clock. Sharding splits the suite across N parallel CI runners, each running 1/N of the files. Combined with Vitest’s per-file in-process parallelism, this can bring CI test wall-clock down to ~1 minute at N=4 (verified locally; see “Measurement” below).

Quick reference

CLI args win over env vars when both are set. Defaults to 1/1 (no sharding) which is safe to use locally. The wrapper writes a per-shard JUnit XML report at reports/test-shards/unit-${shard}-of-${total}.xml so each CI matrix job’s results can be uploaded as a separate artifact without clobbering siblings.

How Vitest sharding works

--shard=$INDEX/$TOTAL partitions the discovered test files (not individual tests) deterministically by hash. Equal TOTAL values across runs produce stable distributions, so a flake in shard 3 can be re-run as --shard=3/4 and pick up the same files. Reference: https://vitest.dev/guide/cli.html#shard
Switching the existing npm run test:coverage step to a sharded matrix is not done in this PR — it’s a CI-workflow change that should land in its own PR after a project owner can validate against billing budgets (matrix runs scale CI minutes linearly; 4 shards × ~1 min ≈ 4 CI minutes total vs 1 × ~4 min ≈ 4 CI minutes, but with 4× the wall-clock parallelism).

Coverage caveat

Coverage thresholds in vitest.config.ts (statements: 40, branches: 35, functions: 40, lines: 40) only make sense on the full suite, not per shard. If we wire sharding to the coverage step, we must also add a “merge coverage” job after the matrix that combines per-shard coverage/coverage-final.json files via nyc merge (or Vitest’s own merge tooling) before checking thresholds. For Phase 1.D, the recommendation is:
  • Use sharding for the fast-feedback unit-tests gate (test:unit:shard).
  • Keep the coverage step single-runner (test:coverage) until merge tooling is proven on this codebase.

Measurement on this branch

Captured on the Cursor Cloud VM (Linux, 4 vCPU / 16 GB RAM), filtering with SKIP_SUPABASE_TESTS=true CI=true: Projected wall-clock at --total=4 (in parallel CI matrix): ~62 s — a ~3.6× speedup vs the unsharded baseline.

See also