Table of content
SHARE THIS ARTICLE
Is this blog hitting the mark?
Contact Us
Table of Contents
- Introduction to Parallelism in Playwright Test
- Worker Processes and Environment Isolation
- Configuring the Number of Workers
- Disabling and Tuning Parallelism
- Parallel Execution Within a Single File
- Enabling Fully Parallel Mode
- Serial Mode for Interdependent Tests
- Opting Out with Describes
- Large-Scale CI: Sharding Tests
- Fail Fast with maxFailures
- Isolating Data per Worker
- Test Ordering Strategies
- Real-World Scenarios: Configuration Use Cases
- Conclusion
Introduction to Parallelism in Playwright Test
Playwright Test runs your tests in parallel using multiple worker processes. Out of the box, test files will execute across different workers, each one running in a fresh OS process (with a fresh browser), allowing for efficient CPU utilization and speedy feedback cycles. Tests within the same file run in order inside a single worker process—unless you choose to override that behavior.
Worker Processes and Environment Isolation
Each Playwright worker operates in complete isolation—its own OS process, its own browser context, and (ideally) its own test data. By design, workers don’t communicate with each other. This prevents test flakiness caused by shared state or side effects across tests. If a test fails, Playwright spins up a new worker to guarantee future runs remain pristine.
Configuring the Number of Workers
Speed up or slow down your suite by adjusting the number of worker processes:
Example:
- Locally, you might set more workers (matching your CPU thread count).
- On CI (where environments are enforced and resources are shared), reduce the count for stability.
npx playwright test --workers 4
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
workers: process.env.CI ? 2 : undefined, // Lower on CI
});
When to use this:
- Perfect for medium/large UI suites with independent tests. If the backend can handle multiple sessions, crank up workers for blazing speeds!
- If too many failures, flaky tests, or server throttling occurs, reduce workers or improve data isolation.
Also Read: Why Software Quality is a Business Risk, Not Just a Technical Concern
Disabling and Tuning Parallelism
Sometimes you need all tests to run serially—maybe the backend isn’t robust or the environment is single-tenant.
npx playwright test --workers=1
export default defineConfig({
workers: 1,
});
When to use this:
- Critical for fragile test environments or migration scripts that must be sequenced strictly.
Parallel Execution Within a Single File
By default, tests inside a file run one after another—but Playwright gives power-users the ability to parallelize these too. Using test.describe.configure({ mode: 'parallel' }) will make Playwright run each test in its own worker, even in the same file.
import { test } from '@playwright/test';
test.describe.configure({ mode: 'parallel' });
test('runs in parallel 1', async ({ page }) => { /* ... */ });
test('runs in parallel 2', async ({ page }) => { /* ... */ });
When to use this:
- Your file is full of truly independent tests (e.g., API contracts, component stories) and you want to cut down file runtime drastically.
- Don’t use if tests share global variables, rely on mutual beforeAll/afterAll hooks, or sequence matters.
Also Read: Are We Truly Covered? Unseen Risks in Software Testing
Enabling Fully Parallel Mode
fullyParallel mode takes parallelism further: not just files, but individual tests across the whole project or a specific browser can all be run independently (with all the usual isolation caveats).
// Globally
export default defineConfig({ fullyParallel: true });
// Per project
export default defineConfig({
projects: [
{ name: 'chromium', fullyParallel: true },
],
});
When to use this:
- Larger CI pipelines, multiple browsers, and sharded runs where every test should be independent. Enable incrementally (project-by-project) to avoid surprises.
Serial Mode for Interdependent Tests
The opposite of parallelism is serial mode. Use test.describe.configure({ mode: 'serial' }) to group tests that must run step-wise (where context, user session, or browser must be shared).
import { test, type Page } from '@playwright/test';
test.describe.configure({ mode: 'serial' });
let page: Page;
test.beforeAll(async ({ browser }) => { page = await browser.newPage(); });
test.afterAll(async () => { await page.close(); });
test('runs first', async () => { /* ... */ });
test('runs second', async () => { /* ... */ });
When to use this:
- Wizard flows, stateful onboarding, or tests walking step-by-step through a process with heavy context reuse. Use sparingly—prefer independence if possible!
Opting Out with Describes
When fullyParallel is defaulted globally, opt out locally from parallelism for specific groups by calling:
test.describe('ordered block', () => {
test.describe.configure({ mode: 'default' });
test('in order 1', async () => {});
test('in order 2', async () => {});
});
When to use this:
- For edge cases where a specific subsetof a file needs to run sequentially.
Large-Scale CI: Sharding Tests
Very large suites benefit from sharding: split your suite across multiple CI agents (machines or containers), each running a distinct ‘slice’ of your tests, greatly reducing wall-clock time.
# 3 shards, run 1 per machine or agent
npx playwright test --shard=1/3
npx playwright test --shard=2/3
npx playwright test --shard=3/3
When to use this:
- Suites that take 10+ minutes, and where you have multiple CI runners/resources available.
Fail Fast with maxFailures
There’s no need to let every test fail if the first few reveal a big regression! The maxFailures config (or CLI flag) stops the run after a certain threshold.
npx playwright test --max-failures=10
export default defineConfig({
maxFailures: process.env.CI ? 10 : undefined,
});
When to use this:
- PR and CI pipelines where fast feedback trumps full reporting during debugging.
Isolating Data per Worker
Parallel tests often need unique data to avoid collisions (like unique users, database rows, environment variables). Use the testInfo.workerIndex property to isolate resources per worker.
// playwright/fixtures.ts
import { test as baseTest } from '@playwright/test';
export const test = baseTest.extend<{}, { dbUserName: string }>({
dbUserName: [async ({}, use) => {
const userName = `user-${test.info().workerIndex}`;
// createUserInTestDatabase(userName)
await use(userName);
// deleteUserFromTestDatabase(userName)
}, { scope: 'worker' }],
});
When to use this:
- Any setup where workers might stomp on each other’s data—unique users for login, isolated DB tenants, file system isolation for upload/download tests.
Test Ordering Strategies
If strict test order is essential (as in orchestration/migration scripts), disable parallelism and use alphabetically named files, or use a "test list" wrapper to control the order, but be aware of caveats:
// test.list.ts
import { test } from '@playwright/test';
import featureB from './feature-b.spec.ts';
import featureA from './feature-a.spec.ts';
test.describe(featureB);
test.describe(featureA);
export default defineConfig({
workers: 1,
testMatch: 'test.list.ts',
});
Real-World Scenarios: Configuration Use Cases
Conclusion
Playwright’s parallelism model unlocks the raw power of your machine and CI environment to deliver fast, scalable, and reliable automated testing—if you take the time to configure it right.
- Use parallelism for speed, but always focus on test isolation.
- Tune settings for your environment, and escalate to full/worker/serial modes as your suite and reliability needs evolve.
- Most importantly: prefer independent, stateless tests, make use of per-worker data isolation, and only force serialization/order when truly unavoidable.
By mastering these configurations, your test suite can be both fast and solid—just the way robust, modern QA should be.
Discover More About QA Services
sales@qable.ioDelve deeper into the world of quality assurance (QA) services tailored to your industry needs. Have questions? We're here to listen and provide expert insights

Viral Patel is the Co-founder of QAble, delivering advanced test automation solutions with a focus on quality and speed. He specializes in modern frameworks like Playwright, Selenium, and Appium, helping teams accelerate testing and ensure flawless application performance.