Subchapter 13.12
references/features-concurrency.mdMarkdown5 KBView on GitHub
By default, Vitest runs test files in parallel across workers:
defineConfig({
test: {
// Run files in parallel (default: true)
fileParallelism: true,
// Max concurrent workers (v4: replaces maxThreads/maxForks; minWorkers removed)
maxWorkers: 4,
// Pool type: 'forks' (default), 'threads', 'vmForks', 'vmThreads'
pool: 'forks',
},
})v4 pool rework:
poolOptionswas removed — all pool settings are now top-level.singleThread/singleForkbecomemaxWorkers: 1, isolate: false. VMmemoryLimitisvmMemoryLimit. These can now be set per project.
Run tests within a file in parallel:
// Individual concurrent tests
test.concurrent('test 1', async ({ expect }) => {
expect(await fetch1()).toBe('result')
})
test.concurrent('test 2', async ({ expect }) => {
expect(await fetch2()).toBe('result')
})
// All tests in suite concurrent
describe.concurrent('parallel suite', () => {
test('test 1', async ({ expect }) => {})
test('test 2', async ({ expect }) => {})
})Important: Use { expect } from context for concurrent tests.
test.sequential/describe.sequential were removed in v5. Use { concurrent: false }:
describe.concurrent('mostly parallel', () => {
test('parallel 1', async () => {})
// Opt this test out of inherited concurrency
test('must run alone', { concurrent: false }, async () => {})
})
// Or an entire suite
describe('sequential suite', { concurrent: false }, () => {
test('first', () => {})
test('second', () => {})
})Set sequence.concurrent: true to make all tests concurrent by default.
Limit concurrent tests:
defineConfig({
test: {
maxConcurrency: 5, // Max concurrent tests per file
},
})Each file runs in isolated environment by default:
defineConfig({
test: {
// Disable isolation for faster runs (less safe)
isolate: false,
},
})Split tests across machines:
# Machine 1
vitest run --shard=1/3
# Machine 2
vitest run --shard=2/3
# Machine 3
vitest run --shard=3/3jobs:
test:
strategy:
matrix:
shard: [1, 2, 3]
steps:
- run: vitest run --shard=${{ matrix.shard }}/3 --reporter=blob
merge:
needs: test
steps:
- run: vitest --merge-reports --reporter=junit# Each shard outputs blob
vitest run --shard=1/3 --reporter=blob --coverage
vitest run --shard=2/3 --reporter=blob --coverage
# Merge all blobs
vitest --merge-reports --reporter=json --coverageControl test order:
defineConfig({
test: {
sequence: {
// Run tests in random order
shuffle: true,
// Seed for reproducible shuffle
seed: 12345,
// Hook execution order
hooks: 'stack', // 'stack', 'list', 'parallel'
// All tests concurrent by default
concurrent: true,
// Order projects/groups run in (3.2+); lower runs first
groupOrder: 0,
},
},
})Randomize to catch hidden dependencies:
// Via CLI
vitest --shuffle
// Per suite
describe.shuffle('random order', () => {
test('test 1', () => {})
test('test 2', () => {})
test('test 3', () => {})
})poolOptions was removed; pool settings are now top-level and can be set per project:
defineConfig({
test: {
pool: 'forks', // 'forks' (default) | 'threads' | 'vmForks' | 'vmThreads'
maxWorkers: 8,
isolate: true, // threads/forks only; vm* pools are always isolated
vmMemoryLimit: '512MB',
},
})For per-project parallelism/isolation settings, see advanced-projects.
Stop after first failure:
vitest --bail 1 # Stop after 1 failure
vitest --bail # Stop on first failure (same as --bail 1)pool: 'forks'); tests within a file run sequentially unless .concurrentconcurrent only speeds up tests that await (I/O, timers); pure sync tests still block the threadexpect in concurrent tests{ concurrent: false } (not .sequential) to opt outmaxWorkers (not maxThreads/maxForks); poolOptions removed in v4--merge-reports combines blob results