Skip to main content
RunBook Academy

Git, CI/CD & GitOpsXLVIII · Conditional ExecutionExpansion

Matrix strategies — when a matrix is right, when it is overused, and the cardinality cost

Intermediate⏱ ~20 mingit

What you'll learn

  • Define a matrix strategy in GitHub Actions and a parallel matrix in GitLab CI
  • Predict the number of jobs produced by a matrix of size M × N
  • Identify the failure mode of a high-cardinality matrix
  • Use `include:` and `exclude:` to refine a matrix without exploding it

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

A matrix strategy expresses run this job N times with these variations. The variations are a set of variables; the matrix expands the job into one job per combination. The discipline is to keep the matrix small, the variables orthogonal, and the cardinality bounded.

The minimum shape

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        node: [18, 20, 22]
    steps:
      - run: tests.sh

Two variables: os (2 values) and node (3 values). The expansion produces six jobs - the Cartesian product.

flowchart LR
    A[test job] --> C["ubuntu-latest, 18"]
    A --> D["ubuntu-latest, 20"]
    A --> E["ubuntu-latest, 22"]
    A --> F["macos-latest, 18"]
    A --> G["macos-latest, 20"]
    A --> H["macos-latest, 22"]

A matrix is right when the variations are orthogonal (a change in os should not change the meaning of node), when each variation produces different signal (OS axis tests platform portability; runtime axis tests runtime compatibility), and when the cardinality is bounded. 2 × 3 = 6 jobs is fine; 10 × 10 = 100 is past the point where the human reading the summary can tell which one mattered.

When a matrix is overused

Three failure modes: combinatorial explosion (three variables of five values each is one hundred and twenty-five jobs); independence violations (a matrix where some combinations are impossible produces failures the team has learned to ignore); hidden coupling (a matrix where one variable secretly depends on another - node: 22 requires a different install step - is a matrix that looks orthogonal and is not).

The discipline is to write the matrix as a flat list of intentional combinations:

strategy:
  matrix:
    include:
      - os: ubuntu-latest
        node: 20
      - os: macos-latest
        node: 20
      - os: ubuntu-latest
        node: 22

Three jobs, all intentional, none impossible. The include: form replaces the implicit Cartesian product with an explicit list.

fail-fast: true (default) cancels in-progress jobs on first failure. fail-fast: false lets every job finish when jobs are independent and the team needs a complete picture. A matrix without include: or exclude: is a Cartesian product - the number of jobs is the product of the variable sizes.

Production discipline

  1. Default to no matrix. A single-job workflow is the most readable form.
  2. Prefer include: to Cartesian. An explicit list documents the intent.
  3. Bound the cardinality. More than roughly twelve jobs and the summary is no longer readable.
  4. Set fail-fast: true unless the team has a reason otherwise.

Cross-course references

  • Linux for Production Sysadmins - Part XXXII covers cross-architecture builds.
  • Terraform for Production Sysadmins - Part XXVII covers multi-region Terraform workflows.

Quiz

Knowledge check · 4 questions

  1. Q1. A matrix declares three variables of five values each. How many jobs does the workflow produce?

  2. Q2. A matrix is the right tool when the variations are coupled - for example, when a `node: 22` combination requires a different install step than `node: 18`.

  3. Q3. A team wants to test on `ubuntu-latest` and `macos-latest`, on Node 20 only. Write the smallest matrix that expresses this intent.

  4. Q4. Diagnose why the CI summary page for a thirty-job matrix has become unreadable, and propose a structural fix.

    The team added a third axis to their existing two-axis matrix (`os: 3 × runtime: 5 × flag: 2`). The matrix produces thirty jobs. Engineers have stopped reading. A real failure two days ago was missed because it sat among twenty-nine green rows.

Passing score: 75%. Answers are checked in this browser.