# GitHub Actions Pricing and Minute Optimization

URL: https://www.devopsness.com/blog/github-actions-pricing
Author: Kiril Urbonas
Published: 2026-07-12
Updated: 2026-10-03
Categories: DevOps
Tags: CI/CD, GitHub Actions, DevOps, Automation, Cost Optimization

Summary: A team was burning 40,000 CI minutes a month and could not say why. Here is how GitHub Actions billing actually works and where the money leaks.

---
# GitHub Actions Pricing and Minute Optimization

GitHub Actions bills private-repo CI per minute once your plan's included minutes run out: as of October 2026, $0.006 for a Linux 2-core runner, $0.010 for Windows, $0.062 for macOS. Public repos and self-hosted runners pay nothing per minute. Almost every surprising bill traces back to one thing: a macOS matrix leg nobody questioned.

A client called us in a mild panic last spring. Their GitHub bill had tripled in two months with no new hires, no new repos, roughly the same commit volume. The culprit was one workflow running a macOS build matrix on every push to every branch. That one job ate more minutes than the rest of the org combined. Here is the billing model, then the handful of changes that actually move the number.

## The model, plainly

Every plan includes a monthly allowance that private repos draw from:

| Plan | Included minutes | Artifact storage | Linux 2-core | Windows 2-core | macOS 3/4-core |
|---|---|---|---|---|---|
| Free | 2,000 | 500 MB | $0.006/min | $0.010/min | $0.062/min |
| Pro | 3,000 | 1 GB | $0.006/min | $0.010/min | $0.062/min |
| Team | 3,000 | 2 GB | $0.006/min | $0.010/min | $0.062/min |
| Enterprise Cloud | 50,000 | 50 GB | $0.006/min | $0.010/min | $0.062/min |

Rates are GitHub's published list prices as of October 2026, after the January 1, 2026 cut of "up to 39%" (Linux 2-core was $0.008 before). Public repos run on standard hosted runners for free, which is a genuinely good deal and worth remembering when you decide what to open-source.

The OS is the real multiplier. Included minutes are consumed at list price, so a macOS minute costs about 10x a Linux minute ($0.062 vs $0.006) and Windows about 1.7x. A build that takes 12 minutes on Linux costs the equivalent of roughly 124 Linux minutes on a Mac runner, and a modest macOS test suite can exhaust a Pro allowance before the month is half over.

Larger runners cost more again: a Linux 4-core is $0.012/min, 8-core $0.022, 16-core $0.042, with Arm64 versions cheaper ($0.008, $0.014, $0.026). Per GitHub's billing docs, larger runners "are always charged for", even in public repos and even when you still have included minutes. Read that before you reach for a 16-core box to "speed things up."

Then there is storage, which people forget entirely. Artifacts are billed per GB against the small allowance in the table. Upload a 300 MB build artifact on every run with the default 90-day retention and you are quietly renting a small warehouse.

Self-hosted runners flip the model. GitHub's docs state Actions usage "is free for self-hosted runners." What you pay for instead is the infrastructure underneath: the EC2 instance, the on-prem box, the patching. For heavy sustained workloads that math often wins, but it is not free, just billed by someone else.

## Where the money actually leaks

Ordered by how much we've seen each one save in practice.

**Cache your dependencies.** This is the biggest single change. If every job reinstalls npm packages or Go modules from scratch, you pay minutes to download the same tarballs forever. The built-in caching in the setup actions turns a three-minute install into fifteen seconds.

```yaml
# .github/workflows/ci.yml
- uses: actions/setup-node@v7
  with:
    node-version: 24
    cache: 'npm'
```

**Stop redundant runs.** Path filters so a docs-only commit does not trigger the full test suite, and concurrency with cancel-in-progress so a fresh push kills the now-pointless run from thirty seconds ago.

```yaml
# .github/workflows/ci.yml
on:
  push:
    paths:
      - 'src/**'
      - 'package.json'

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true
```

That `cancel-in-progress` line alone cut one team's minute usage by a fifth. They force-pushed to feature branches constantly and every push spawned a full run nobody waited for.

**Have matrix discipline.** A matrix of 3 OSes by 4 language versions is 12 jobs. Do you support all twelve, or did someone copy a template? Trim it to what you ship, and set `fail-fast` deliberately rather than by default.

**Use Linux unless you have a reason not to.** Everything runs on Linux; Windows and macOS jobs are exceptions you justify. If you ship a macOS app you need Mac runners for the final build and notarization. You do not need them for linting.

**Move the heavy, frequent jobs to self-hosted runners.** For a workload that runs constantly and eats hours, [self-hosted runners](/blog/self-hosted-runners-cost) can be dramatically cheaper than hosted minutes. Keep occasional jobs on GitHub's fleet where you do not babysit a machine.

**Set artifact retention deliberately.** The default is 90 days. Most CI artifacts are useless after a day.

```yaml
# .github/workflows/ci.yml
- uses: actions/upload-artifact@v7
  with:
    name: build
    path: dist/
    retention-days: 3
```

## A worked example

A private repo on the Team plan (3,000 included Linux minutes, worth $18 at list price). CI runs 200 times a month.

The bad version: a 4-job matrix, two Linux and two macOS, 10 minutes each, no caching, running on every push including docs.

- 2 Linux jobs: 200 x 2 x 10 = 4,000 minutes x $0.006 = $24
- 2 macOS jobs: 200 x 2 x 10 = 4,000 minutes x $0.062 = $248

That is $272 at list price, minus the $18 allowance: about $254 a month for one repo's CI, and over 90% of it is the macOS legs.

The fixed version: one macOS job that only runs on tags, caching that shaves each Linux job to 4 minutes, path filters that cut runs to 140.

- 2 Linux jobs cached: 140 x 2 x 4 = 1,120 minutes x $0.006 = $6.72
- 1 macOS job, 10 tags a month: 10 x 10 = 100 minutes x $0.062 = $6.20

Total: $12.92, inside the $18 allowance. You pay nothing, with the same coverage on the things that matter.

## Questions people ask

### How much does GitHub Actions cost per minute in 2026?

As of October 2026, GitHub's list prices are $0.006 per minute for a standard Linux 2-core runner, $0.010 for Windows 2-core, and $0.062 for macOS 3/4-core. Larger Linux runners run $0.012 (4-core) to $0.042 (16-core), with Arm64 cheaper. You only pay after your plan's included minutes are used, except on larger runners, which are always billed.

### Are GitHub Actions minutes free for public repositories?

Yes. Standard GitHub-hosted runners are free in public repositories. The exception is larger runners: GitHub bills those even for public repos. Private repositories draw from the plan allowance first: 2,000 minutes on Free, 3,000 on Pro and Team, 50,000 on Enterprise Cloud, then pay the per-minute rate.

### Does GitHub charge for self-hosted runners?

Not as of October 2026. GitHub announced a $0.002 per-minute "cloud platform charge" for self-hosted runner usage starting March 1, 2026, then postponed it to "re-evaluate our approach." GitHub's billing docs currently state Actions usage is free for self-hosted runners. You still pay for the machines themselves, so budget the instance cost and maintenance time.

## The decision, concretely

- **Bill jumped and nobody knows why?** Open the billing usage report first. It is almost always a macOS or Windows leg, or an uncached workflow on every push.
- **Shipping a Mac or iOS app?** Keep macOS, but only for release builds and tags. Lint and unit-test on Linux.
- **Sustained heavy CI on private repos?** Price out self-hosted runners against $0.006 a minute; past a few thousand hours a month they usually win.
- **Reaching for larger runners?** Remember they never touch your included minutes. Cache first, then size up.

## The call we'd make

Default to Linux, cache aggressively, kill redundant runs with concurrency, and only reach for self-hosted runners once a workload is heavy enough to justify owning the machine. Fix the macOS leg and the uncached install and most bills fall back to sane. If you are still shopping for a [CI/CD platform](/blog/best-cicd-platforms) and cost decides it, Actions is competitive as long as you respect the OS price gap. Ignore it and it will quietly bleed you.

## Sources

- [GitHub Docs: Actions runner pricing](https://docs.github.com/en/billing/reference/actions-runner-pricing)
- [GitHub Docs: GitHub Actions billing, included minutes and storage](https://docs.github.com/en/billing/concepts/product-billing/github-actions)
- [GitHub: 2026 pricing changes for GitHub Actions](https://github.com/resources/insights/2026-pricing-changes-for-github-actions)
- [GitHub Docs: Artifact and log retention defaults](https://docs.github.com/en/organizations/managing-organization-settings/configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-organization)

