In this article, I’ll talk about why using sharding in Playwright automation projects is so important, how it affects your test durations, and how you can use it effectively based on your project needs.
Without sharding, all tests are distributed among the workers within a single pod.
When sharding is enabled, the test suite is divided into multiple shards, and each shard runs its own workers on separate pods.
This allows true multi pod parallelism.
- Workers → parallel test executors within the same pod
- Shards → distribute the test suite across multiple pods
To enable sharding, simply add the following option to the end of your test command.
Here, x represents the active shard index, and y represents the total number of shards:
--shard=x/y
If you’re using sharding, the fullyParallel parameter becomes even more important.
When this parameter is set to true, all your tests are divided and executed across the shards.
If it’s set to false, the distribution happens on a file basis — meaning entire test files are assigned to shards rather than individual tests.
However, there’s an important nuance here: even when fullyParallel is set to false, the same test file can still run on different shards if it’s executed under multiple projects defined in your Playwright configuration.
For example, a basket1.spec.ts file might run on one shard for the project1 project and on another shard for the project2 project.
You can add sharding to your YAML configuration as shown below:
parallel: 4
script:
- npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
Tip: If you’re using npm run or yarn run, you need to add an extra -- before your Playwright arguments.
npm run test -- --shard=1/4
In our automation project, we built a login system that assigns different users to each worker within a spec file to prevent them from interfering with one another.
However, this setup introduced flakiness in our tests when running with Playwright’s fullyParallel parameter — both in true and false modes.
To overcome this issue, we started manually assigning spec files to specific shards , giving us full control over how tests are distributed.
If you’re facing a similar problem, you can configure your YAML file as shown below.
parallel:
matrix:
- SPEC_FILE: "basket1.spec.ts basket2.spec.ts"
- SPEC_FILE: "basket3.spec.ts checkout.spec.ts checkout2.spec.ts"
- SPEC_FILE: "checkout3.spec.ts basket4.spec.ts"
- SPEC_FILE: "checkout4.spec.ts"
When doing so, it’s important to keep the completion times of shards as close as possible to optimize the overall pipeline duration.
If one spec file takes significantly longer than others, consider splitting it into multiple smaller specs and assigning them to different shards — this can lead to a noticeable time gain.
For example, in our project, the checkout4.spec.ts file used to take much longer than other specs.
By splitting it into two separate specs and assigning them to different shards, we were able to significantly reduce the total test duration.
Before
After
After completing the sharding setup, the next important step is merging the reports generated by the shards.
To merge the reports, you need to set the reporter type in your Playwright configuration to blob.
The blob reporter is mergeable and can be converted into other reporting formats. It can include screenshots, traces, and other attachments , making it ideal for shard-based parallel test runs.
You can add the following setting to your configuration file:
export default defineConfig({
testDir: './tests',
reporter: process.env.CI ? 'blob' : 'html',
});
To merge your reports, you can run the following command:
npx playwright merge-reports --reporter html ./all-blob-reports
Here, the --reporter parameter specifies which format the blob reports will be converted to , and the path at the end points to the folder containing the blob reports to merge.
Additionally, if you have multiple reporting configurations or want to generate multiple report types from blob reports, you can create a separate config file and pass it to the merge-reports command.
For example, in our project, we generate both HTML and Allure reports.
Here’s the merge.config.ts we use:
export default {
testDir: 'tests',
reporter: [['html', { open: 'never' }],
['allure-playwright', {
outputFolder: "allure-results",
}],
['json', { outputFile: 'playwright-report/test-results.json' }]],
};
You can then use this config file in the merge step as follows:
npx playwright merge-reports --config merge.config.ts ./blob-report
After completing the merging step, let’s look at how sharding improved our test durations in the project.
In our automation project, we divide our tests into different schedules based on tags for example, schedule1, schedule2, and so on. The impact of our sharding structure on these schedules is shown in the table below.
Thanks for the readings 🎭




Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.