GitHub Actions Pricing in 2026, and What the Other Three Meter
Hosted runners got cheaper in January and the per-job rounding rule still quietly costs you more than any of it. And before you price a move to GitLab, CircleCI, or Buildkite: none of the four bill the same unit.
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.
The other three do not meter the same thing
Before pricing a move, notice that the four platforms do not bill the same unit, which is why the marketing numbers refuse to line up.
| Unit on the meter | Free tier | Paid entry | |
|---|---|---|---|
| GitHub Actions | Job minutes, rounded up per job | 2,000 min (Free), 3,000 (Pro and Team) | $0.006 per Linux minute |
| GitLab CI | Compute minutes on shared runners only | 400 min, 5 users per top-level group | Premium $29 per user per month, 10,000 min included |
| CircleCI | Credits, scaled by machine size | 30,000 credits, 5 active users | Performance from $15 per month, +$15 per extra user |
| Buildkite | vCPU minutes on hosted agents | 2,000 Linux vCPU min, 5 users | Pro $30 per active user per month, 4,000 vCPU min included |
Read the Buildkite row twice. A vCPU minute is not a build minute. Run a job on a four-vCPU machine and one wall-clock minute costs you four, so the “2,000 minutes” in the free tier is 500 minutes of a modest machine. Buildkite’s rates start at $0.004 per Linux vCPU minute and $0.02 per Mac vCPU minute, and the older story that Buildkite sells only orchestration while you bring all your own compute is out of date. Self-hosted agents still work, and hosted ones are now a product.
CircleCI’s credits work the same way. A Linux Medium burns 10 credits a minute, so the 30,000 free credits are 3,000 minutes on that machine and 6,000 on a small Docker class. That is not the unusually generous free tier it looks like next to a raw credit count. Extra credits are $15 per 25,000, which lands the effective Linux rate within a rounding error of GitHub’s $0.006. The two are not accidentally similar.
GitLab is the one with a structurally different answer, and it is in the footnotes rather than the table: execution on your own runners does not consume compute minutes at all and is unlimited. So GitLab’s per-minute overage rate only ever applies to shared runners, and a team that already self-hosts pays the seat price and nothing else. Free gives 400 compute minutes with 5 users per top-level group, Premium is $29 per user per month billed annually with 10,000, and Ultimate is quote-based with 50,000.
The comparison that actually matters is therefore not price per minute. It is which unit your workload is expensive in. A team running wide test matrices on small machines is cheap in vCPU minutes and expensive in job minutes, because of GitHub’s per-job rounding. A team running long builds on big machines is the reverse.
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.
Self-hosting is the other lever, and it has a rough crossover. Below about 100,000 minutes a month, hosted runners are the pragmatic choice: you are spending a few hundred dollars and skipping the work of maintaining a fleet, which is cheap against an engineer’s time. Above it the arithmetic flips, because none of these meters offer a volume discount. The ten-thousandth minute costs what the first one did, so overage grows linearly forever while a self-hosted fleet on spot instances flattens out.
The tax on self-hosting is a person. Someone patches the runners, tunes the autoscaler, keeps jobs isolated from each other, and carries the pager when the fleet wedges at 2am. If that someone is a named platform engineer, self-hosting past 100,000 minutes is a clear win. If it is whoever notices, the savings go back out as incidents. Budget the human, not only the instances.
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 and the only one whose model changes the answer, because self-hosted execution there is uncapped and free of compute minutes. But migrating means moving or mirroring your repositories, which is a much larger commitment than swapping a runner label, and if you are not already paying for GitLab the seat price swamps the CI saving. CircleCI is fast, its layer caching is good, and its pricing sits close enough to GitHub’s that a move for cost alone rarely repays the disruption. Buildkite is worth a look if you already run your own fleet and want orchestration that assumes you do.
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.