Sharding & Cloud Execution — Unlimited Scale
Parallelism maxes out a single machine. Sharding breaks the physical barrier by distributing tests across multiple cloud machines. Learn how to turn a 40-minute suite into a 4-minute suite.
📖 The Story: The CI Bottleneck
Sarah's team had mastered parallelism. They configured 8 workers on their CI machine. Their 800-test suite ran in 20 minutes. But as the app grew to 1,200 tests, the suite time crept up to 35 minutes.
They tried increasing workers to 16, but the CI machine ran out of RAM and crashed. They were stuck. The physical limits of a single cloud instance were blocking them from scaling their test suite.
Then Sarah implemented sharding. She configured her CI pipeline to spin up 5 separate machines simultaneously. Each machine ran 1/5th of the test suite (240 tests each) using 4 workers. The total execution time plummeted from 35 minutes to 7 minutes.
Parallelism scales within a machine. Sharding scales across machines.
🎯 Why Shard?
Cloud Scaling
Break free from single-machine RAM and CPU limits. Use as many cloud instances as you need.
Instant Feedback
Turn 40-minute CI blocks into 5-minute CI blocks. Developers get feedback before they context-switch.
Cost Efficiency
5 machines running for 5 minutes is often cheaper (and faster) than 1 machine running for 40 minutes in cloud pricing models.
🌍 Real World Example
You have 1,000 tests. Your CI provider allows 10 parallel jobs. You configure a 10x10 matrix. 10 machines spin up. Each machine receives 100 tests. If 100 tests take 3 minutes to run, your entire 1,000-test suite finishes in 3 minutes.
🧒 Explain Like I'm 10
Imagine you have to deliver 100 pizzas. You have one car. You can fit 5 pizzas in the car at a time. So you make 20 trips. That's parallelism (loading the car efficiently).
But 20 trips still takes 2 hours. So, you rent 10 cars and hire 10 drivers. You give each driver 10 pizzas. Now all 100 pizzas are delivered in 1 trip. That's sharding (using multiple machines).
🎓 Professional Explanation
Sharding is the process of splitting a test suite into discrete chunks (shards) that can be executed independently on different CI runners. Playwright supports this natively via the --shard=x/y CLI flag, where x is the current shard index and y is the total number of shards.
Playwright uses a deterministic hashing algorithm to assign test files to shards. This ensures that --shard=1/4 always runs the exact same subset of tests, which is critical for debugging and caching.
📊 Single Machine vs Sharding
⚙️ The --shard Flag
You don't need to change your test code to shard. You just change how you invoke the Playwright CLI.
# Run the first quarter of the suite npx playwright test --shard=1/4 # Run the second quarter of the suite npx playwright test --shard=2/4 # Run the third quarter of the suite npx playwright test --shard=3/4 # Run the fourth quarter of the suite npx playwright test --shard=4/4
Playwright automatically calculates which test files belong to 1/4, 2/4, etc. You don't have to manually split your files.
☁️ CI Matrix Strategy (GitHub Actions)
To automate spinning up multiple machines, use your CI provider's matrix strategy.
name: Playwright Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false # Don't cancel other shards if one fails matrix: shard_index: [1, 2, 3, 4] steps: # ... setup node, install deps ... # Run Playwright with the dynamic shard index - name: Run tests run: npx playwright test --shard=${{ matrix.shard_index }}/4 # Upload the blob report artifact for merging - name: Upload blob report uses: actions/upload-artifact@v3 with: name: blob-report-${{ matrix.shard_index }} path: blob-report retention-days: 1
🔗 Merging Reports
When sharding, each machine generates a partial report. To see the full suite results in one place, you must configure Playwright to generate "blob" reports, and then merge them in a final CI job.
1. Configure Blob Reports
export default defineConfig({ reporter: [['blob', { outputDir: 'blob-report' }], ['html']] });
2. Add a Merge Job in CI
merge-reports: runs-on: ubuntu-latest needs: [test] # Wait for all shards to finish steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 # Download all artifacts from all shards - uses: actions/download-artifact@v3 with: path: all-blob-reports # Merge them into a single HTML report - name: Merge into HTML Report run: npx playwright merge-reports --reporter html ./all-blob-reports # Upload the final merged report - uses: actions/upload-artifact@v3 with: name: html-report path: playwright-report
⚠️ Common Mistakes
Mistake 1: Manual File Splitting
# ❌ BAD: Manually passing files to different machines npx playwright test tests/auth/ --workers=4 npx playwright test tests/cart/ --workers=4 # ✅ GOOD: Let Playwright shard automatically based on x/y npx playwright test --shard=1/2 npx playwright test --shard=2/2
Manual splitting leads to unbalanced loads (e.g., Auth might take 1 min, Cart might take 5 min). Playwright's hash algorithm distributes files evenly across shards based on total file count.
Mistake 2: Forgetting fail-fast: false
By default, GitHub Actions cancels all other jobs in a matrix if one fails. If Shard 2 fails, Shards 1, 3, and 4 are killed, meaning you can't see if they passed or failed. Always set fail-fast: false.
✅ Best Practices
- Balance your test files. If you have one massive file with 200 tests, it will bottleneck a shard. Keep files small.
- Use
fail-fast: falsein CI matrices to see all failures, not just the first one. - Always merge reports. A CI pipeline with 4 separate HTML reports is frustrating to review. Merge them.
- Don't over-shard. 100 shards for 100 tests is slower than 1 shard, because machine spin-up time exceeds test execution time.
🏗️ Senior Engineer Deep Dive
The Sharding Hash Algorithm
How does --shard=1/4 know which tests to run? Playwright hashes the file path of every test file. It then uses modulo arithmetic: hash(file) % totalShards === shardIndex - 1. Because the hash is deterministic, 1/4 always gets the exact same files. This is critical for caching—if a file hasn't changed, CI systems can skip running that specific shard.
Cloud Provider Limits
Sharding is bound by your CI provider's concurrent job limit. GitHub Actions free tier allows 20 concurrent jobs. Enterprise allows 180. If you need 200 shards, you either need enterprise CI, or a specialized testing cloud like BrowserStack or Sauce Labs.
💼 Interview Questions
Show Answer
Show Answer
strategy.matrix with a list of shard indexes (e.g., [1, 2, 3, 4]). Then pass the index to the Playwright CLI: npx playwright test --shard=${{ matrix.shard_index }}/4. Set fail-fast: false so all shards complete.Show Answer
npx playwright merge-reports --reporter html to combine them.Show Answer
🏋️ Practical Exercise
Simulate Sharding Locally
- Open two terminal windows.
- In Terminal 1, run
npx playwright test --shard=1/2 --reporter=line. - In Terminal 2, run
npx playwright test --shard=2/2 --reporter=line. - Observe that different test files run in each terminal simultaneously.
- Verify that together, they ran 100% of your suite.
🚀 Mini Project
🏗️ GitHub Actions Sharded Pipeline
Create a real sharded CI pipeline.
- Push a Playwright project to GitHub.
- Create a GitHub Actions workflow with a 4-part matrix (
[1, 2, 3, 4]). - Configure
fail-fast: false. - Run the tests using
--shard=${{ matrix.shard_index }}/4. - Add a final job (
needs: [test]) that merges the reports and uploads the final HTML artifact. - Trigger the workflow and download the final merged report.
📝 Quiz
Test your understanding. Click an option to check your answer.
--split x/y--shard x/y--parallel x/y--matrix x/y--shard=x/y flag tells Playwright to run only the x-th portion of the suite out of y total shards.fail-fast: false in a CI matrix?fail-fast: false ensures all shards finish, giving you a complete failure report.npx playwright merge-reports.npx playwright combine-reportsnpx playwright merge-reportsnpx playwright build-reportnpx playwright shard-mergenpx playwright merge-reports --reporter html ./path-to-blobs combines the blob reports into a final HTML report.fail-fasttest.shard()❓ FAQ
Q: Can I shard tests within a single file?
A: No. Playwright shards at the file level. If you have a massive file, you must manually split it into multiple files to distribute them across shards.
Q: Do shards share cookies or local storage?
A: No. Shards run on entirely different machines. They do not share any state. If tests require authentication, each shard must perform the globalSetup independently.
Q: Does sharding work with BrowserStack or Sauce Labs?
A: Yes. You can run Playwright shards locally (or in CI) and point them to a remote cloud grid. This allows for virtually unlimited concurrency.
📦 Summary
🎯 Key Takeaways
- Sharding splits tests across multiple CI machines.
- Use the
--shard=x/yflag to execute a specific portion of the suite. - Use a CI matrix to spin up multiple machines dynamically.
- Always set
fail-fast: falseto see all failures. - Generate blob reports and merge them for a single unified HTML report.
- Don't over-shard. Machine spin-up time can exceed test time for small suites.
