The free tier is generous, but not infinite
GitHub Actions billing is built around runner-minutes. The free tier looks like this (numbers as of 2026; check the docs for current values):
- Public repos — completely free. Unlimited minutes on standard Linux runners. (Larger runners and self-hosted are still free.)
- Private repos (Free plan) — 2,000 Linux minutes/month per account.
- Private repos (Pro) — 3,000.
- Private repos (Team) — 3,000.
- Private repos (Enterprise) — 50,000.
Beyond the free quota, you pay per minute. Crucially, runner type matters:
- Linux — 1× rate.
- Windows — 2× rate.
- macOS — 10× rate (the most expensive line item in CI bills, often by far).
- Larger runners (4-core, 8-core, GPU) — multiplied rates.
Where the bills actually grow
- macOS runners. If you have an iOS or macOS-only test, audit how often it runs. Cap to merge-to-main only if PRs don't need it.
- Cron schedules that fan out. A nightly that triggers a 30-job matrix burns through minutes.
- Re-run on every push. Use
concurrencygroups to cancel in-progress runs when a new push lands on the same branch. - Tests that don't need to run on this PR. Use
paths:filters orchanged-filesactions to skip.
Most teams overpay for CI by 2–3× simply because nobody audits the spend.