Skip to content
compiler.dev

What Is a Matrix Build in GitHub Actions?

Last updated

A matrix build is a GitHub Actions strategy that expands one job definition into many parallel jobs, one for every combination of the variables you list, such as operating system and language version.

How it works

You add strategy.matrix to a job and list values for one or more keys. GitHub creates one job per combination, each on its own runner. Inside the job you read the current values with ${{ matrix.<key> }}.

Two lists of three values produce nine jobs. The count multiplies quickly, and each job consumes CI minutes, so a wide matrix can get expensive.

Example

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        node: [20, 22]
        include:
          - os: ubuntu-latest
            node: 24
        exclude:
          - os: windows-latest
            node: 20
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci && npm test

Useful options

  • include adds extra combinations or extra variables to existing ones.
  • exclude removes combinations you do not want.
  • fail-fast (default true) cancels remaining jobs when one fails. Set it to false when you want the full picture.
  • max-parallel limits how many matrix jobs run at once.

You can preview the expansion with the matrix expander tool. The full guide is GitHub Actions matrix builds.

Common mistakes

  • Matrix where it is not needed. Testing three Node versions for an app that only ships on one wastes minutes.
  • Leaving fail-fast on while debugging. One flaky leg cancels the others and hides real failures.
  • Matrix for speed. A matrix of identical jobs does not split work. To split one test suite across machines, use test sharding.
  • Too many required checks. Each matrix leg is a separate check name, which complicates branch protection.
  • Exceeding limits. A single matrix is capped at 256 jobs per workflow run.

FAQ

What is the difference between a matrix and test sharding?

A matrix runs the whole job under different configurations. Sharding splits one configuration's tests into slices. You can combine them, using a shard index as a matrix variable.

Does a matrix run jobs in parallel?

Yes, as far as runner capacity and concurrency limits allow. Use max-parallel to throttle.

Can the matrix be generated dynamically?

Yes. One job can output JSON and a later job reads it with fromJSON in strategy.matrix.