# What a self-hosted GitHub runner really costs

> Self-hosted GitHub runner cost is zero on your GitHub Actions bill and not zero for you: the break-even against hosted rates, and the postponed fee.

Source: https://latchkey.dev/learn/cost/self-hosted-github-runner-total-cost  
Updated: 2026-09-20

Self-hosted GitHub runner cost is not a line on your GitHub invoice: GitHub's billing documentation still states that Actions usage is free for self-hosted runners, and the $0.002 a minute platform charge announced for 1 March 2026 was postponed before it took effect. What you pay instead is compute by the hour rather than by the job minute, plus the engineering time the fleet consumes, and the second one is what decides whether self-hosting was cheaper.

The honest version of this comparison is a break-even, not a verdict. A GitHub-hosted standard Linux runner costs $0.006 a minute, which is $0.36 for an hour of job time, billed only while a job runs. Your own instance costs whatever it costs every hour it is switched on, whether or not a job is running on it.

So the whole question is utilization, and after that it is ops. This page does the first part with published numbers and hands you the inputs for the second, because nobody can tell you what an hour of your team's time is worth.

## What GitHub charges today: nothing

GitHub's billing documentation is unambiguous: Actions usage is free for self-hosted runners. No orchestration fee, no per-job fee, no queue fee. You register a runner, it takes jobs, and none of it reaches the invoice.

That was very nearly not true. On 16 December 2025 GitHub announced a $0.002 per minute Actions cloud platform charge on self-hosted usage in private repositories from 1 March 2026, alongside a cut of up to 39 percent in hosted prices on 1 January. The price cut happened. The charge did not: GitHub postponed it "to take time to re-evaluate our approach", and it has not returned.

Plan for the published number, which is zero, and know the size of the drafted one: at $0.002 a minute, 100,000 self-hosted minutes a month would have carried $200 before a single instance was paid for.

## The number you are trying to beat

A standard GitHub-hosted Linux x64 runner is $0.006 a minute, or $0.36 per hour of job time, and GitHub bills only the minutes your jobs actually run, rounded up to the whole minute per job. Private repositories get 2,000 to 50,000 included minutes a month depending on plan, which come off the top.

Notice the shape of that bill. It is elastic: a quiet week costs nothing, and you never pay for a machine that is waiting. A self-hosted fleet inverts that. You pay for the waiting, and the jobs are free.

## What a self-hosted fleet actually costs

The instance bill is the obvious part and rarely the largest one. The parts that get left out of the spreadsheet are the ones that make a self-hosted fleet look cheaper than it is.

Idle time is the biggest of them. CI load is bursty, so a fleet sized for the Tuesday afternoon peak is mostly idle at 4am, and your cloud provider bills an idle hour at the same rate as a busy one.

- Compute, billed by the wall-clock hour the instance exists, not by the job minute.
- Idle capacity: the gap between the fleet you sized and the jobs that arrived.
- Storage and egress: runner images, caches, container layers pulled on every cold runner.
- Image maintenance: the toolchains GitHub-hosted images ship with are now yours to build and patch.
- Operations: scaling, upgrades, stuck runners, full disks, and the pager that goes with them.
- Security: an ephemeral runner per job is a design decision you now have to implement, not a default you inherit.

```.github/workflows/ci.yml
# The workflow side of self-hosting is one line. Everything above is the other side.
jobs:
  build:
    runs-on: [self-hosted, linux, x64, ci-pool]
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v7
      - run: make test
```

## The break-even, in one line of arithmetic

An hour of job time costs $0.36 on a standard hosted Linux runner. Your fleet delivers an hour of job time for its hourly instance price divided by its utilization, because at 25 percent utilization the fleet has been switched on for four hours to deliver one hour of work.

So the break-even instance price is $0.36 multiplied by your utilization. At a genuinely saturated 100 percent, an instance may cost up to $0.36 an hour and still be cheaper. At 50 percent, $0.18. At 25 percent, which is a realistic figure for a fleet that also has to absorb peaks, $0.09. At 10 percent, $0.036, which is below the price of almost anything with a CPU in it.

That ceiling is before storage, before egress, and before a single hour of anyone's time. If the postponed $0.002 platform charge ever arrives, every ceiling in that list falls by a third, because the budget to beat drops from $0.006 a minute to $0.004.

```gha-runner-scale-set values.yaml
githubConfigUrl: https://github.com/your-org
githubConfigSecret: arc-github-app
runnerScaleSetName: ci-pool

# minRunners is the dial this whole page is about: every warm runner is an hour
# you pay for whether a job arrives or not, and every cold start is a queue.
minRunners: 0
maxRunners: 20
```

| Fleet utilization | Break-even instance price per hour | If the $0.002 charge returns |
| --- | --- | --- |
| 100% | $0.360 | $0.240 |
| 50% | $0.180 | $0.120 |
| 25% | $0.090 | $0.060 |
| 10% | $0.036 | $0.024 |

> Computed from the $0.006 per minute standard Linux x64 rate in [Actions runner pricing](https://docs.github.com/en/billing/reference/actions-runner-pricing), read 20 September 2026, and the $0.002 per minute charge described in [GitHub's changelog](https://github.blog/changelog/2025-12-16-coming-soon-simpler-pricing-and-a-better-experience-for-github-actions/). The Helm values above are the real keys from the gha-runner-scale-set chart, read the same day.

## A worked example, with the inputs written down

Take 100,000 private-repository Linux minutes a month, which is 1,667 hours of job time. On standard hosted runners that is $600, less whatever your included minutes cover: $582 on a Team plan, $300 on Enterprise Cloud.

To beat $600, the entire self-hosted fleet has to come in under $600 a month. At 25 percent utilization the fleet is switched on for 6,667 instance-hours to deliver those 1,667 hours of work, so the instances must average less than $0.09 an hour. Every hour of engineering time you spend on the fleet comes out of the same $600: at a loaded cost of $100 an hour, six hours a month is $600, which is the entire budget.

Run the same numbers at 60 percent utilization and the ceiling rises to $0.216 an instance-hour, which is where a well-packed fleet of committed-spend instances starts to look genuinely cheap. The variable that decides this comparison is not the instance price list. It is how much of the month your runners are actually working.

## When self-hosting wins, and when it does not

Self-hosting wins when the machine is the point. GPU builds, Apple silicon at a scale GitHub does not sell, hundreds of gigabytes of disk, or jobs that must sit inside your VPC next to the data they test against: in those cases a hosted runner is not what you need at any price. It also wins at high, sustained utilization on committed cloud spend.

It loses on bursty, low-utilization workloads, on small teams where ops hours are a large share of the total, and on Windows or macOS fleets where the machines are expensive and the tooling is worse. It also loses quietly, which is the dangerous case: the invoice arrives at the cloud provider, not at GitHub, so nobody compares the two.

A managed runner is the third option and it is priced like the first: Latchkey publishes $0.0025 a minute at 2 vCPU, billed per job minute with no fleet to keep warm, which puts an hour of job time at $0.15 against the $0.36 hosted rate. That is the comparison to run before you decide the only way down from $0.006 is your own hardware, and [how Latchkey cuts the GitHub Actions bill](/github-actions-cost-reduction) is the case for it.

## How to compare without fooling yourself

Price engineering hours, not just instances. A fleet that saves $200 of compute and costs an engineer a day a month has saved nothing. Put the hours in the same spreadsheet as the instance bill, at your real loaded hourly cost.

Count the re-runs on both sides. A job that dies because a runner ran out of disk is minutes paid for nothing, and self-hosted runners fill up in ways hosted ones do not, because the disk is yours and it persists. [Freeing disk space on GitHub Actions runners](/learn/failures/free-disk-space-on-github-actions-runners) measures what a cleanup actually reclaims.

Then check the assumption underneath the whole exercise. If the reason you are self-hosting is the per-minute rate, compare that rate against every option before you take on a fleet: [how GitHub Actions pricing works](/learn/cost/github-actions-pricing-explained) has the published numbers, the [GitHub Actions cost calculator](/learn/cost/github-actions-cost-calculator) prices your own month, and [macOS runner cost](/learn/cost/github-actions-macos-runner-cost) covers the one platform where the rate really is the problem.

## FAQ

### Per minute charges for self hosted runners?

None today. GitHub announced a $0.002 per minute Actions cloud platform charge on self-hosted runner usage in private repositories, to start on 1 March 2026, then postponed it and has not rescheduled it. The billing documentation still says Actions usage is free for self-hosted runners. Public repository usage was never in scope.

### Is GitHub Actions free for self-hosted runners?

From GitHub, yes: no per-minute charge, no orchestration fee, and no consumption of your included minutes. The cost is entirely yours, in compute hours, storage, images and operations. That is a different statement from "free", and the gap between the two is what this page prices.

### When do self-hosted runners actually cost less than GitHub-hosted?

When the fleet is busy enough that its hourly price divided by its utilization comes in under $0.36 an hour of job time, and when the ops hours fit inside whatever is left. High sustained utilization, committed cloud spend, or hardware GitHub does not sell are the cases that clear that bar. Bursty low-volume CI almost never does.

### Is the GitHub Actions control plane no longer free?

It is still free. The charge that would have priced it, $0.002 a minute on self-hosted usage in private repositories, was announced for March 2026 and postponed, and the billing documentation is unchanged. Self-hosted usage is not metered at all today, so it draws nothing from your included minutes either.

## References

- [GitHub Actions billing: Actions usage is free for self-hosted runners (verified 2026-09-20)](https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions)
- [GitHub Changelog: update to GitHub Actions pricing and the postponed self-hosted charge (verified 2026-09-20)](https://github.blog/changelog/2025-12-16-coming-soon-simpler-pricing-and-a-better-experience-for-github-actions/)
- [GitHub: Actions runner pricing, every per-minute rate by runner (verified 2026-09-20)](https://docs.github.com/en/billing/reference/actions-runner-pricing)
- [actions-runner-controller: gha-runner-scale-set chart values (verified 2026-09-20)](https://github.com/actions/actions-runner-controller/blob/master/charts/gha-runner-scale-set/values.yaml)
- [Latchkey pricing: published per-minute runner rates (verified 2026-09-20)](https://latchkey.dev/pricing)

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
