How to run Playwright Tests in Parallel on GitLab


TL;DR
Add parallel: N
to your GitLab CI job and pass --shard=${CI_NODE_INDEX}/${CI_NODE_TOTAL}
to Playwright to slash your test execution time and keep your team shipping fast.
The Backstory
Last week, our test suite execution time crossed the dreaded 30-minute mark. Team members were context-switching during test runs, and our deploy frequency started to suffer. That's when I discovered we weren't using GitLab CI's parallelization capabilities with our Playwright tests.
The Problem
Running Playwright tests sequentially in GitLab CI can take forever, especially as your test suite grows. Without parallelization, even simple PR validations become coffee-break-length waits:
# The slow, sequential way 😴
test:
stage: test
image: mcr.microsoft.com/playwright:v1.51.1-noble
script:
- npm install
- npx playwright test
artifacts:
when: always
paths:
- playwright-report/
- junit.xml
reports:
junit: junit.xml
The Insight
GitLab CI supports running jobs in parallel using the parallel
keyword, and Playwright can shard tests with the --shard
flag. Combining these powers is like discovering you can breathe underwater:
# The speed-demon parallel way 🚀
test:
stage: test
image: mcr.microsoft.com/playwright:v1.51.1-noble
parallel: 5 # Run 5 parallel jobs
script:
- npm ci
- npx playwright test --shard=${CI_NODE_INDEX}/${CI_NODE_TOTAL}
artifacts:
when: always
paths:
- playwright-report/
- junit.xml
reports:
junit: junit.xml
Playwright's --shard
flag takes two parameters: current shard index and total shards. The magic here is that GitLab CI automatically provides environment variables CI_NODE_INDEX
and CI_NODE_TOTAL
that perfectly match what Playwright expects!
Why It Matters
After implementing this change:
Our test suite execution time dropped from 30+ minutes to under 10 minutes
Developers stopped context-switching during test runs
We caught integration issues faster and deployed more frequently
For larger projects, you can refine this further by using GitLab's matrix syntax to run different browser tests in parallel:
test:
stage: test
image: mcr.microsoft.com/playwright:v1.51.1-noble
parallel:
matrix:
- BROWSER: [chromium, firefox, webkit]
script:
- npm install
- npx playwright test --project=$BROWSER --shard=${CI_NODE_INDEX}/${CI_NODE_TOTAL}
artifacts:
when: always
paths:
- playwright-report/
- junit.xml
reports:
junit: junit.xml
Subscribe to my newsletter
Read articles from Hermann Kao directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Hermann Kao
Hermann Kao
Software developer documenting my journey through web and mobile development. I share what I learn, build, and struggle with—from React to SwiftUI, architecture decisions to deployment challenges. Not an expert, just passionate about coding and learning in public. Join me as I navigate the tech landscape one commit at a time.