Matrix math: when one push quietly fans out into 25 jobs
A build matrix is a multiplier, and multipliers are easy to stop noticing. Three operating systems times three language versions is nine jobs; add an arch axis and you're at eighteen — per push. The bill and the queue both scale with a number most people have never actually computed for their own workflow.
Compute your number
Multiply the lengths of every list under strategy.matrix (then add include: entries, subtract exclude: matches). If the result surprises you, that's the point of this exercise. Every one of those legs is a separate billable job, and if some run on macOS or Windows, the expensive multiplier compounds the wide one.
When big is correct
sharp ships prebuilt native binaries, and its build matrix is about 25 legs — Linux x64/arm, Windows x64/arm, macOS Intel/arm, plus Alpine containers — with fail-fast: false so every platform reports even when one breaks. That's not waste: every leg produces an artifact users install. It's also the test for your own matrix: does each leg produce something distinct that you ship or genuinely support? If a leg exists because it was in the template, it fails that test.
The slim-PR / full-main split
Most regressions surface on one representative leg. Run the slim set on every PR and the full grid where it matters:
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest]
node: [22]
include:
# full grid only on main / nightly
- { os: macos-latest, node: 22 }
- { os: windows-latest, node: 22 }
# gate the extra legs:
if: github.event_name != 'pull_request' || (matrix.os == 'ubuntu-latest')(Or keep two workflows: a slim pull_request one and a full push-to-main one — easier to read than per-leg conditions.)
fail-fast: know which mode you're in
The default (true) cancels every other leg when one fails — right for PR feedback, wrong when you need the full platform picture (sharp turns it off deliberately). Whichever you choose, cap every leg with timeout-minutes: a matrix multiplies a hung job's cost by its width.
Find out what your matrix expands to
GitSpider's scan computes the expansion for every workflow and flags matrices past ~12 legs on active repos — the "wait, it runs HOW many jobs?" moment, automated.
These hide across however many workflow files you have, which is exactly why nobody sits down and fixes them. Point GitSpider at your repo and it flags which patterns apply, with the fix for each.
No signup. Public repos only. ~30 seconds.