Free tools Windows power users keep installed
One-click scans. No signup required.
Parallelize automated tests only after each test can run independently: it must create and own the state it needs, avoid modifying resources used by other tests, and clean up after itself. Then raise worker counts gradually, monitor failures and resource pressure, and add CI shards only when the suite and its dependencies can handle the extra load. A retry that passes is a clue to investigate—not proof that the test is reliable.
Why parallel tests become flaky
Parallel execution exposes dependencies that sequential runs can hide. One test may leave a database row that another expects to be absent; two tests may edit the same account; or a test may depend on global state, execution order, or cleanup that happens only after success. pytest’s documentation specifically notes that parallel runs can reveal flakiness related to ordering, leftover data, and global state: pytest: Flaky tests.
As an Amazon Associate I earn from qualifying purchases.
A failure that appears only when another test runs first or at the same time is evidence to investigate coupling or contention. It is not, by itself, a reason to increase the worker count or add retries.
Make each test own its state
Set up the data the test needs
Have each test create the records and state it depends on rather than relying on another test to prepare them. Where practical, namespace records by test or worker, make setup safe to repeat, and avoid having concurrent tests edit the same shared entity. Cleanup should run after both successful and failed tests.
#1 Best Overall
Isolate browser and backend state
For browser automation, a fresh browser session does not automatically isolate shared backend data. Playwright uses separate worker processes and isolated browser contexts; its documentation shows using a worker index to distinguish test database users. See Playwright: Parallelism and sharding. Selenium’s guidance recommends creating a new WebDriver instance per test and avoiding shared test data to simplify isolation: Selenium: Avoid sharing state.
Apply the same principle beyond browser tests: check shared accounts, database rows, fixed filenames, global variables, persistent browser storage, and external services. Any resource modified by more than one test needs isolation, coordination, or a reasoned limit on concurrency.
Rank #2
Increase concurrency in measured steps
Start with a conservative, explicit worker limit in CI. Playwright’s CI guidance recommends workers: 1 when stability and reproducibility are the priority, while allowing parallel tests on powerful self-hosted CI systems. That is framework-specific guidance, not a universal worker count: Playwright: CI.
- Establish a baseline. Run the suite with a known worker setting and record the environment and setting alongside the results.
- Increase gradually. Raise concurrency in steps rather than jumping straight to the machine’s maximum. Compare failures, timeouts, CPU and memory pressure, and load on shared services after each change.
- Back off when failures rise. If failures or timeouts grow with worker count, reduce concurrency while checking for resource contention and shared state. A slower but reproducible run is more useful than a faster run whose results cannot be trusted.
Use CI sharding to distribute independent work
Workers run tests concurrently within a runner; sharding divides work among separate CI jobs. Playwright, for example, supports commands such as npx playwright test --shard=1/4, with each shard assigned to a job. Sharding distributes work; it does not fix tests that share state.
Choose the right shard granularity
With Playwright’s fullyParallel: true, tests can be distributed at test granularity. Without it, shards are assigned whole files, so files of different sizes can leave some jobs with more work than others. See Playwright: Sharding tests.
Check whether the distribution helps
Shards shorten the overall run only if CI can execute them concurrently and the suite’s databases, APIs, and other dependencies can sustain the combined load. Compare shard durations: the slowest shard determines when the full run finishes. Playwright’s sharding guide also describes generating blob reports and merging shard results into an HTML report, so the distributed run can be reviewed together.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Investigate retries instead of treating them as a fix
A test that fails and then passes has demonstrated intermittent behavior; the passing retry does not show that the original failure was harmless. Preserve the first failure and the retry outcome, then investigate the cause—such as a race, uncontrolled state, an overly strict timing assertion, or an environment limit.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →pytest notes that rerunning failures can mitigate the disruption caused by flaky tests, and points to replay and randomized-order plugins as ways to reproduce or expose problems. Use those techniques to gather evidence and fix the underlying cause, rather than using retry success as a reliability signal: pytest: Flaky tests.
Quick Recap
Best Value
Capture evidence that makes failures diagnosable
- Keep the worker setting and run environment with each result so you can compare behavior at different concurrency levels.
- For UI failures, retain useful artifacts such as screenshots or video; pytest’s guidance recommends these for investigating failures.
- Try a different or randomized test order when order dependence is suspected.
- When a run is sharded, merge reports where supported so failures and outcomes can be reviewed across the complete run.
Choose the throughput change that fits the bottleneck
| Option | What it changes | What to watch |
|---|---|---|
| More workers on one runner | Runs more tests concurrently on the same machine. | CPU, memory, timeouts, and load on shared services; lower the limit if failures rise with concurrency. |
| More CI shards | Distributes independent work across CI jobs. | Whether jobs can run at the same time, whether dependencies can handle the combined load, and whether shard durations are balanced. |
| Test-level rather than file-level sharding | Can distribute work more finely in Playwright when fullyParallel: true is enabled. |
Whether tests are genuinely independent; finer distribution does not remove state coupling. |
| Retries | Can reduce disruption from intermittent failures while retaining evidence of them. | Keep the initial failure visible and investigate; a passing retry does not establish reliability. |
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




