GitHub Actions Pricing 2026: Full Breakdown + 7 Cost Cuts
Hosted runners got cheaper in January, the self-hosted charge got announced and withdrawn in a day, and the per-job rounding rule is still quietly costing you more than any of it.
GitHub restructured Actions pricing at the start of 2026. Hosted runners got cheaper. Then GitHub tried to put a per-minute charge on self-hosted runners as well, the community objected loudly, and the change was withdrawn inside a day.
If you run hosted runners on private repos your bill went down without you doing anything. If you self-host, nothing changed. The episode is still worth understanding, because the economics that prompted it have not gone anywhere.
Rates below were checked against GitHub’s billing docs on 21 August 2026.
What the runners cost now
| Runner | Per minute |
|---|---|
| Linux 2-core | $0.006 |
| Windows 2-core | $0.010 |
| macOS 3 or 4-core | $0.062 |
The restructure cut raw compute by roughly 40% and folded a $0.002 per minute platform charge, covering the orchestration layer, into the per-minute rate. You just see a smaller number.
Included minutes per month did not change: 2,000 on Free, 3,000 on Pro, 3,000 on Team, and 50,000 on Enterprise Cloud. If you have read somewhere that Team gets 50,000, that is Enterprise Cloud’s number and it is a wrong one to budget against. Public repos still get hosted runners for free.
The self-hosted charge that lasted a day
Buried in the same announcement as the price cuts: from March, self-hosted runners on private repos would carry the same $0.002 per minute platform charge.
Think about what that means. Self-hosted runners run on your hardware. You already pay for the machines, the power, the maintenance. Avoiding GitHub’s compute bill is the entire point.
The argument was not unreasonable. The control plane does real work: parsing YAML, queueing jobs, distributing them, collecting logs, handling secrets. That costs GitHub money whether or not you use their compute.
The execution was the problem. It arrived attached to genuinely good news, and for a team burning a hundred thousand self-hosted minutes a month it was an extra two hundred dollars for something that had been free. The objection was less about the amount than the precedent.
GitHub reversed inside 24 hours and said they had missed the mark by not including more people in the planning. The charge is shelved with no new timeline. Self-hosted usage is free today.
I would not plan on that being permanent. The control plane still costs money to run, and a company that tried once tends to try again with better packaging.
Seven things that actually cut the bill
Cache what does not change. The highest-impact optimization and still the most commonly skipped. Key the cache on lockfile hashes rather than branch names or dates, so you get hits across pull requests that share a dependency tree.
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
Cancel superseded runs. Three pushes in quick succession do not need three full runs. This one is free money, because most people push again before the first run finishes.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
Filter by path. A fifteen-minute pipeline should not run because someone fixed a typo in the README. Separate, lightweight workflows for docs and config.
Gate the expensive jobs behind the cheap ones. If linting catches a syntax error in thirty seconds there is no reason to have started a ten-minute integration suite. You save those minutes on every failed run, which is the run you have most often.
Watch the per-job rounding. GitHub bills each job rounded up to the nearest minute. Five jobs of twenty seconds each is five billed minutes. One job doing all five steps in a hundred seconds is two. This cuts directly against the usual advice to keep jobs small and parallel, and both pieces of advice are right: parallelize where wall-clock time matters to a human waiting, consolidate where it does not.
Stay on Linux unless the job genuinely needs otherwise. Look at the chart again. Cross-compilation, container builds, and most test suites run fine on Linux even when production is not. Reserve macOS for what actually requires it: Xcode builds, platform UI tests, notarization.
Audit monthly. The billing dashboard breaks usage down by workflow and repository, and there is an API if you want alerts. You will find workflows running more often than anyone intended and abandoned configs in repos nobody touches, and both are pure waste.
Third-party runners, and whether to leave
Above a few hundred dollars a month, third-party runner providers are worth pricing. They take the same workflow YAML, so migration is changing runs-on and adding a setup step, and they generally offer faster machines for less.
Leaving Actions entirely is a different question, and the answer is usually no. Its advantage was never price. It lives where the code already is, the event model is welded to pull requests and releases, and there is an action for nearly everything.
GitLab CI is the strongest all-in-one alternative, but migrating means moving or mirroring your repositories, which is a much larger commitment than swapping a runner label. CircleCI is fast and its layer caching is good, and its free tier is thin.
The sensible order is: optimize what you have, then swap runner providers if you are still spending too much, and only consider a platform move if you have a reason beyond cost.
What I would actually do this week
Open the billing dashboard and sort workflows by minutes. Then look at the top three and ask whether each one needed to run every time it ran.
In my experience the answer is no for at least one of them, and the fix is four lines of YAML rather than a migration.