Skip to content

3 Implementation Patterns to Maximize Parallel Execution with GitHub Actions Matrix Build

Target Audience

  • DevOps engineers (intermediate level) who understand GitHub Actions basics

Key Points

  1. Simultaneous testing across multiple environments with Matrix strategy
  2. Automatic build target determination with dynamic Matrix generation
  3. Reduced wasted execution time with fail-fast control

Why This Matters Now

Current CI/CD times exceed 30 minutes in large projects. By properly utilizing Matrix Build, parallel execution can reduce execution time by over 60%. Effectively utilize GitHub Actions' free tier of 2000 minutes/month.

Solution Steps Overview

StepContentSuccess Metric
1Basic Matrix setup3 environments parallel
2Dynamic Matrix generationBuild changed files only
3Optimization settings60% time reduction

Step 1: Parallel Testing with Basic Matrix Configuration

Run tests simultaneously across multiple Node.js/Python versions and different operating systems.

name: Matrix Build
on: [push, pull_request]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        node: [18, 20, 22]
        exclude:
          - os: macos-latest
            node: 18
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm test

This configuration runs 5 combinations (Ubuntu×3 + macOS×2) in parallel.

Step 2: Efficiency with Dynamic Matrix Generation

Execute only necessary builds based on changed files.

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v4
      - id: set-matrix
        run: |
          if git diff --name-only HEAD^ | grep -q "frontend/"; then
            echo "matrix={\"app\":[\"frontend\"]}" >> $GITHUB_OUTPUT
          elif git diff --name-only HEAD^ | grep -q "backend/"; then
            echo "matrix={\"app\":[\"backend\"]}" >> $GITHUB_OUTPUT
          else
            echo "matrix={\"app\":[\"frontend\",\"backend\"]}" >> $GITHUB_OUTPUT
          fi

  build:
    needs: prepare
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
    steps:
      - run: echo "Building ${{ matrix.app }}"

Step 3: Optimization with fail-fast and max-parallel

Minimize resource consumption with immediate stop on error and parallel execution control.

strategy:
  fail-fast: true  # Stop all if one fails
  max-parallel: 4  # Limit concurrent executions
  matrix:
    python: [3.9, 3.10, 3.11, 3.12]
    test-group: [unit, integration, e2e]

Common Pitfalls and Solutions

SymptomCauseImmediate Solution
Matrix expansion errorJSON syntax errorEcho check before fromJson()
Waiting for parallel limitmax-parallel not setSet limit to 2-4
Unnecessary combinations runexclude not usedExplicitly specify exclusions
Advanced Settings (High-level Optimization) ### Speed Up with Cache Integration
- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-${{ matrix.node }}-npm-${{ hashFiles('**/package-lock.json') }}
### Conditional Matrix
matrix:
  include:
    - os: ubuntu-latest
      node: 20
      run-e2e: true
    - os: windows-latest
      node: 20
      run-e2e: false