← Back to libraryQuestion 223 of 273
🔧CI/CDIntermediate

Parallel Jobs & Matrix Builds

📌 Definition:

Parallelism runs independent jobs simultaneously on separate runners to cut wall-clock time. A matrix build is a concise way to generate many parallel jobs from a set of variables — for example, the same tests across multiple browsers, operating systems, or Node versions.

📖 Detailed Explanation:

There are two complementary forms of parallelism. Job-level parallelism runs different kinds of work at once (unit, API, E2E jobs side by side). Matrix parallelism expands one job definition across a combination of parameters, so { browser: [chromium, firefox, webkit] } produces three jobs from one block. Matrices multiply: adding os: [ubuntu, windows] to the three browsers yields six jobs. This is powerful for coverage but can explode runner usage and cost, so you use include/exclude to prune nonsensical or low-value combinations. Sharding is a special case: split one large test suite into N slices that run in parallel and merge the reports afterward. The main correctness caveat is shared external state — parallel jobs hitting the same database or account will collide unless data is isolated per job.

🔑 Key Points:
  • Job-level parallelism: run different work (unit/API/E2E) at the same time
  • Matrix: expand one job across variables (browser × os × version)
  • Matrices multiply — prune with include/exclude to control cost
  • Sharding splits one suite into parallel slices, then merges reports
  • Isolate external state (DB rows, accounts) so parallel jobs don't collide
🌍 Real-World Example:

A suite must run on Chromium, Firefox and WebKit across Ubuntu and Windows. A 2×3 matrix generates six parallel jobs from a few lines of YAML, finishing in the time of the slowest single combination rather than six runs back-to-back — but the team excludes WebKit-on-Windows since that combination isn't a real target, saving a runner.

📎 Code Example:
jobs:
  e2e:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        browser: [chromium, firefox, webkit]
        exclude:
          - os: windows-latest
            browser: webkit      # not a real target — prune it
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npx playwright install --with-deps
      - run: npx playwright test --project=${{ matrix.browser }}

# Sharding a single big suite across 4 parallel jobs:
#   matrix: { shard: [1,2,3,4] }
#   run: npx playwright test --shard=${{ matrix.shard }}/4
🎯 Scenario-Based Interview Question:

Scenario: A team adds an os × browser × node-version matrix to 'be thorough'. CI now spawns 48 jobs per PR, the monthly runner bill triples, and most combinations test nothing meaningful. How do you make the matrix sensible?