Self-hosting your GitHub Actions runners can eliminate a significant cloud line item. The math changed in 2026: GitHub cut hosted runner prices by 25% in January, and is evaluating a new fee for self-hosted runners in private repos. This post gives you a framework to evaluate the decision with current numbers -- not a sales pitch for either direction. The "when not to self-host" section is as important as the rest of it.
The 2026 pricing context (read this first)
Two things changed in early 2026 that affect this decision.
1. GitHub cut hosted runner prices effective January 1, 2026:
| Runner | Old rate/min | New rate/min | Change |
|---|---|---|---|
| Linux standard (x64) | $0.008 | $0.006 | -25% |
| macOS standard | $0.080 | $0.062 | -22.5% |
| Windows standard | $0.016 | $0.010 | -37.5% |
2. GitHub proposed a $0.002/min fee for self-hosted runners in private repos (announced December 2025, originally set to take effect March 2026). The fee was postponed after significant community backlash and is under re-evaluation as of April 2026. It is not currently in effect. That said, it's worth factoring into any long-term ROI calculation -- if enacted, it would add a meaningful cost to every self-hosted minute in private repos.
These two changes together mean: self-hosting is still cheaper at scale, but the margin narrowed compared to 2024-2025 analysis. The directional math holds; the specific savings figure does not.
When GitHub-hosted runners are the right call
Self-hosting is not the right default. In these situations, staying on GitHub-hosted runners is the correct answer:
Small team (under 10 engineers). At $0.006/min, a team running 50 jobs/day at 4 minutes per job pays roughly $26/month. The operational overhead of running a Kubernetes cluster for CI isn't worth saving $26/month.
No existing infrastructure. If you're provisioning machines exclusively for CI, factor in the full compute cost -- not just what the VMs cost at the margin. The ROI calculation changes substantially when you can't amortize the hardware against other workloads.
macOS builds at low volume. Even at $0.062/min, 50 macOS CI minutes/day totals around $82/month. Below the overhead threshold for most teams.
No platform owner. If no engineer can spend 2-4 hours/month on runner operations, that time cost outweighs the savings for any team spending less than ~$1,000/month on CI.
GitHub-hosted runners are zero maintenance, start in seconds, and the bill is often lower than the engineering time to manage alternatives. For small teams, stay hosted.
When the math flips
The economics change when several factors converge:
Your monthly GitHub Actions bill exceeds $500. At this level, the overhead of a self-hosted setup starts paying back within weeks or months -- not years.
You already have underutilized compute. If you run a Kubernetes cluster or bare metal servers for your product that aren't fully utilized, CI workloads can run on spare capacity at near-zero marginal cost.
macOS builds are significant. At $0.062/min, the math moves fast: 500 macOS minutes/day = $40/day = $1,240/month. Two Mac Mini M4s ($599 each, $1,198 total) pay back in under a month. Real-world data: Jeff Verkoeyen cut his macOS CI bill from approximately $4,167/month to approximately $68/month using Mac Minis (October 2025).
Privacy or compliance requirements. GitHub-hosted runners are managed VMs with no data residency guarantees. For regulated workloads or teams with contractual data residency requirements, self-hosted is often a compliance requirement, not just a cost decision.
The hidden costs of self-hosting
Be honest about what self-hosting adds. The per-minute comparison between GitHub-hosted and self-hosted misses most of the real cost.
Kubernetes infrastructure baseline. EKS control plane: ~$73/month fixed. NAT gateway: $30-100/month depending on traffic. EBS storage per node, egress charges for Docker image pulls. These costs exist even when no CI is running. See the detailed cost breakdown for line-item numbers.
ARC controller maintenance. Actions Runner Controller has had breaking changes -- the 0.12.0 release required a full reinstall of the scale set configuration. Tracking upgrades and testing them before they break your fleet takes real engineering time.
Runner image maintenance. Custom runner images with your toolchain need to stay current with OS patches, dependency updates, and GitHub Actions runner binary releases. A stale image that causes a build failure during a deployment is an incident.
Cold starts. With minRunners: 0, runner pod provisioning adds 30-60 seconds of overhead before jobs start. See the ARC setup guide for warm pool configuration that eliminates cold starts.
Engineering time. Fleet operations, debugging, capacity planning, on-call for runner failures. Rule of thumb: if no one can dedicate 2-4 hours/month to runner ops, the time cost outweighs savings for most teams spending less than $1,000/month on runner minutes.
The hybrid model: self-hosted base load, cloud for spikes
The practical approach most mature engineering teams settle on: self-hosted handles the predictable, daily CI volume; GitHub-hosted handles release days, large matrix builds, and spikes that exceed fleet capacity.
How the routing layer works:
- GitHub emits a
workflow_job.queuedwebhook when a job enters the queue. - A routing evaluator checks current fleet capacity -- idle runners vs. busy runners.
- If capacity is available: job dispatches to ARC self-hosted runners. Compute cost: near zero (amortized hardware).
- If the fleet is at capacity: routing evaluator lets GitHub assign the job to hosted runners as overflow.
- No workflow file changes required. The
runs-onlabel stays as-is.
Result: most of your daily CI volume on self-hosted at near-zero compute cost, with a guaranteed fallback so builds don't queue indefinitely when the fleet is saturated.
A simple decision framework
Three questions determine whether self-hosting pays:
1. What's your monthly GitHub Actions bill?
Under $300: probably not worth the overhead yet. $500-$1,000: worth evaluating. Over $1,000: almost certainly worth it.
2. Do you already have underutilized compute?
If yes, the marginal cost of adding CI workloads is near zero. If no, factor in full compute provisioning cost before comparing to GitHub-hosted rates.
3. Do you have a platform owner?
If no dedicated person can own runner operations, the ops burden lands on product engineers at the worst possible times.
If: big bill + existing compute + platform ownership → self-hosting pays.
If: small bill or no platform owner → stay hosted.
Worked example with 2026 rates
Setup: 30-engineer team, 600 CI jobs/day (mix of standard and PR workflows), average 7 minutes per job, 22 working days per month.
GitHub-hosted only:
600 jobs x 7 min x $0.006/min x 22 days = ~$554/month
With hybrid routing (80% self-hosted, 20% GitHub-hosted overflow):
Self-hosted infrastructure adjusted for business hours (10 hrs/day):
- 3x c5.xlarge spot x $0.05/hr x 10 hrs/day x 22 days = ~$33/month
- EKS control plane + NAT + storage: ~$123/month
- Self-hosted infrastructure: ~$156/month
GitHub-hosted overflow (20% of jobs):
600 x 0.20 x 7 min x $0.006/min x 22 days = ~$111/month
Total hybrid: ~$267/month
Net savings vs. hosted-only: ~$287/month (~52%)
If the self-hosted platform fee is enacted at $0.002/min: add approximately $185/month → net savings drop to ~$102/month. Still positive, but narrower.
Note: if you're running Kubernetes for other workloads already, the $156/month infrastructure cost drops significantly -- potentially to near zero for the CI component.
Stratus handles the routing layer -- self-hosted first, cloud overflow automatically when your fleet is at capacity. If the economics are on your side:
Join the waitlist →