DEV Community

A.F.
A.F.

Posted on • Originally published at gitspider.com

Your GitHub Actions bill is mostly macOS minutes (here's how to tell)

If your GitHub Actions bill surprises you, look at the macOS line first. A macOS runner minute bills at roughly ten times a Linux minute, and the xlarge tiers cost more still. One ten-minute macOS job is a hundred Linux-equivalent minutes. Run it on every PR and it is almost certainly the biggest single line on your bill.

The multipliers

  • Linux is the baseline (about $0.006/min on a standard 2-core runner in 2026).
  • Windows bills roughly 2x Linux.
  • macOS bills roughly 10x Linux, and the arm64 xlarge tiers bill above that.

The billing page shows minutes. It does not shout about the multiplier. Ten thousand macOS minutes and ten thousand Linux minutes look the same in a usage table and differ by an order of magnitude in dollars.

How serious projects end up here

Not by accident, exactly. By default-following. vscode's PR pipeline calls its darwin test workflow four times per pull request, each on runs-on: macos-14-xlarge. For an editor that ships a native macOS app, that is a defensible choice made by a team with a Microsoft-sized budget. The pattern to copy is the deliberateness, not the config: most repos running macOS jobs on every PR are not shipping macOS binaries. The job landed in a template years ago and nobody priced it since.

What actually needs macOS

  • Xcode builds, iOS/macOS app compilation, simulator tests
  • Code signing and notarization
  • Reproducing genuinely platform-specific bugs (filesystem case-insensitivity, BSD userland)

What doesn't: your unit tests, your linter, your web build "just to be safe." If the job would pass in a Linux container, it is paying a 10x premium for nothing.

The fixes, cheapest first

1. Move Linux-capable jobs off premium runners. Usually a one-line change:

jobs:
  test:
    runs-on: ubuntu-latest  # was macos-latest — ~10x cheaper
Enter fullscreen mode Exit fullscreen mode

2. Gate macOS to where it earns its rate. Run it on the default branch or a release tag, not every PR commit:

jobs:
  macos-test:
    if: github.ref == 'refs/heads/main'   # PRs run the Linux leg only
    runs-on: macos-14
Enter fullscreen mode Exit fullscreen mode

3. Trim the matrix. A full OS x version grid multiplies the premium legs with everything else. And set timeout-minutes everywhere it hurts most: a hung macOS job burns the 6-hour default at 10x the rate.

Find every premium-runner job you have

I built a free scanner for exactly this class of config waste: it flags every workflow using macOS or Windows runners, plus the other quiet defaults (missing timeouts, no concurrency group, uncached dependencies) with copy-paste fixes. Two minutes to find out which of your workflows are on the expensive tier: gitspider.com/scan


This is a syndicated version of the full guide, which also covers the free-plan macOS concurrency cap and per-stack examples.

Top comments (1)

Collapse
 
topstar_ai profile image
Luis

Great write-up. GitHub Actions cost optimization is often overlooked because teams focus on build speed first and only investigate costs after the bill becomes noticeable.

The macOS runner issue is a good example of why visibility matters. Expensive infrastructure choices can hide behind simple workflow files, especially when teams inherit CI/CD pipelines without reviewing execution patterns.

A few additional optimizations I’ve found useful:

Measure runner usage by workflow/job before changing anything
Cache dependencies aggressively (but avoid stale cache complexity)
Split heavy jobs into Linux-based workloads when possible
Use matrix builds carefully since parallelism can multiply costs quickly
Track build duration trends to identify regressions

For larger teams, CI observability should be treated like production observability — knowing which repository, workflow, and engineering activity consumes resources is key.

The best optimization is usually not “make CI faster at any cost,” but designing the pipeline so each minute provides real value.

Thanks for sharing the practical approach. 🚀