The matrix Directive

matrix generates parallel stages from axes: each combination of values is a cell that runs the matrix's stages with the values as environment variables; excludes removes combinations, and a cell may have its own agent, environment, when, input, options, tools and post. Inside a stage Compatibility of an agent none pipeline, BookNest tests Node.js 22 2,131 and 24 against PostgreSQL 17 1,289 and 18, minus one pairing:

decl-matrix (excerpt): three cells from two axes and an excludeGroovy
      matrix {
        agent { label 'linux' }
        axes {
          axis { name 'NODE_VERSION'; values '22', '24' }
          axis { name 'POSTGRES'; values '17', '18' }
        }
        excludes {
          exclude {
            axis { name 'NODE_VERSION'; values '22' }
            axis { name 'POSTGRES'; values '18' }
          }
        }
        stages {
          stage('Test') {
            steps { sh 'echo "node:$NODE_VERSION + postgres:$POSTGRES at $(date +%T)"' }
          }
        }
      }
Output
node:22 + postgres:17 at 14:53:54
...
node:24 + postgres:17 at 14:53:55
...
node:24 + postgres:18 at 14:53:56

The branches were named Matrix - NODE_VERSION = '22', POSTGRES = '17' and so on. Each cell asked for its own linux agent, so on agent-1's single executor they ran one after another. A real matrix would give each cell a node:${NODE_VERSION} container (docker Agent Directives). Cells multiply (three axes of four values are 64), so exclude aggressively.