Guide to GitHub Actions Runners: Hosted, Self-Hosted, and Third-Party Options
runs-on: ubuntu-latest looks like a small config line, but it decides more than most teams realize: what hardware your jobs run on, how fast caches restore, and how much visibility you get when something breaks. Workflow tweaks help, but the runner underneath still sets the ceiling.

There are three main runner models behind that label: GitHub-hosted runners, self-hosted runners on your own infrastructure, and third-party managed runners that drop into the same workflow. Teams often ask how these options differ, so this post breaks down the tradeoffs.
TL;DR
- Three options behind
runs-on: GitHub-hosted (commodity hardware, zero ops, a black box when it fails), self-hosted (your hardware, your on-call), and third-party managed (drop-in fleets, often 2x faster or more). - Hosted to third-party is a label change, not a full migration. Self-hosting is the opposite.
- The speed-ups come from both hardware and caching. How caching is built and where it lives, both matter.
- GitHub's proposed self-hosted runner fee (announced December 2025) is still postponed and not in effect as of June 2026, whatever some comparison pages claim.
The three options at a glance
Option 1: GitHub-hosted runners
The default starting point for plenty of teams. You get a clean VM per job, 2 vCPUs on the standard tier, with larger runners (up to 64 vCPUs) and GPU runners available on Team and Enterprise plans.
What makes the baseline slow isn't the core count, it's the silicon under it. RunsOn's CPU benchmark puts GitHub's x64 runners on older server parts (Intel Xeon Platinum 8370C, AMD EPYC 7763) at around 2,200 single-thread Passmark points, roughly half the 4,300 to 4,500 that current-generation runners from Avrea, Namespace, Blacksmith, and RunsOn post. Their summary is clear: "GitHub runs older CPUs overall, most visibly on x64" (runs-on.com/benchmarks). Most CI time is CPU-bound, compiling and running tests, so that per-core deficit shows up directly in build time.
The obvious next step is a bigger runner, and it does help, but only with part of the problem. More vCPUs speed up work that parallelizes: test sharding, parallel jobs and concurrent builds. What they don't change is per-core speed, because it's the same commodity silicon, just more of it. Anything that doesn't parallelize, a serial test suite or a single-threaded build step, runs no faster on a 32-core runner than a 2-core one. And a bigger box does nothing for the cache: GitHub's actions/cache rehydrates over the network from GitHub storage, capped at 10 GB and slow to restore, with no built-in Docker layer caching, so every run re-pulls dependencies and rebuilds layers it finished yesterday. You can buy more cores from GitHub, not faster ones, and you are still waiting on the network.
The last gap is visibility. You get a log stream and an exit code, but not much else: no per-step CPU or memory, no way to SSH into a job to see why it hung and no signal on which step actually cost you the time.
Pricing: public repos are free; private repos get 2,000 to 3,000 free minutes a month depending on plan. After that, the standard Linux 2-core x64 tier is $0.006/min following the January 2026 cuts (1-core is $0.002/min), scaling proportionally with size. macOS is the expensive outlier: GitHub's fastest Apple Silicon option, a 5-core M2 Pro, lists at $0.102/min. These move, so check the pricing page before you quote it.
Right call when: builds are light, volume is low, or you would rather not own any infrastructure. For most public repos it is the correct default.
Option 2: Self-hosted runners
You register your own machines and GitHub schedules jobs onto them. Going self-hosted is what you do when you need something the hosted fleet can't give you: specific hardware (GPUs, big disks, more cores), access to a private network, or data that can't leave your environment.
On paper it looks cheap: better hardware and more control for what seems like the cost of the compute alone. The real cost is mostly operational. You own provisioning, image building, caching, autoscaling, patching, and the page at 2am when the fleet wedges. The default runner is also persistent, so state leaks between jobs and you inherit a class of flaky failures unless you build ephemeral runners yourself. GitHub's own hosted-versus-self-hosted writeup is a good place to reason through the real total cost of ownership: the infrastructure, staffing, and support that the per-minute compute price hides. It is a useful read, though like this post it is of course not purely objective. They are in the business of selling you build minutes, after all.
There is also a security cost that is easy to underestimate. That same non-ephemeral default means a single compromised job, from a malicious dependency or a poisoned action, can backdoor the runner and reach into the jobs that run after it. GitHub puts it plainly: self-hosted runners "do not have guarantees around running in ephemeral clean virtual machines, and can be persistently compromised by untrusted code in a workflow" (GitHub secure-use docs). And because the runner usually sits inside your network, that foothold has line of sight to internal services, secrets, and the cloud metadata endpoint, which is why GitHub's guidance is to put runners behind a zero-trust, defense-in-depth setup. It is not theoretical: attackers have used self-hosted runners as backdoors in the wild (Sysdig). Public repos are even riskier, which is why GitHub says not to put self-hosted runners on them at all, but the exposure does not vanish on private ones.
Tools can reduce the operational burden: Actions Runner Controller (ARC) for autoscaling on Kubernetes, RunsOn for ephemeral runners in your own AWS account, Actuated for bring-your-own-hardware microVMs. They help, but you are still running infrastructure.
About the fee: in December 2025 GitHub announced a $0.002/min charge on self-hosted minutes in private repos, set for March 1, 2026, then postponed it indefinitely after the backlash (paying GitHub to orchestrate hardware you already own did not land well). It has not taken effect as of June 2026. Comparison pages still citing it as live are wrong.
Right call when: you need the hardware or the network access, the data-residency requirement is hard, and you have a platform team with the cycles to own it.
Option 3: Third-party managed runners
This is the middle path: faster runners without owning the fleet. You point runs-on at a managed provider and keep the rest of your workflow intact. The provider owns the runner fleet, caching layer, images, scaling, and maintenance.
The difference from self-hosting is not just hardware speed. Self-hosted can be just as fast on a cold build if you rent the same class of hardware. The harder part is everything around it: fast cache restores, sane eviction, Docker layer reuse, package proxies, image updates, autoscaling, and keeping the fleet healthy as workloads change.
That is the real case for a managed provider: you get the runner fleet, caching work, and maintenance without turning CI infrastructure into an internal product. At Avrea, this is the work we focus on. Making the GitHub Actions cache up to 6x faster was one example, and we wrote up the details here.
This is now a real category, not just a cheaper GitHub runner market. There are multiple options with a slightly different focus.
BuildJet, a well-known runner provider until recently, shut down its GitHub Actions service in 2026, with runners offline as of March 31, so it is not included above.
How to choose
Start with the constraint, not just the feature list.
You're just getting started, you need CI to work and your builds are light. Stay on GitHub-hosted. Even with the quick migration, it might not be worth adding another vendor.
You need specific hardware, GPUs, or private-network access, and you have a platform team that can afford to own CI infrastructure. Self-host, and use ARC or RunsOn so you are not building the orchestration from scratch.
Your builds are slow and you don't want a big project to fix it. Use a third-party managed runner. This is the sweet spot for teams in the 50 to 500 engineer range, where CI runs hundreds of times a day and ten wasted minutes per run is a tax on everyone.
One trend worth naming: as teams adopt AI coding tools, commit and PR volume climbs and CI is increasingly what can't keep up. The faster you generate code, the more the runner becomes the bottleneck. But the runner is only the first one. Scaling CI is a moving target: speed up the hardware and jobs start queueing on concurrency limits; raise those and the cache thrashes against its 10 GB cap; fix the cache and the flaky tests that were noise at ten PRs a day are constant at a hundred. Every jump in volume surfaces the next bottleneck, and the work is never finished.
How to switch without rewriting workflows
Hosted to third-party is a label swap. Install the provider's GitHub App, change the label, done:
runs-on: avrea-ubuntu-latest # was: ubuntu-latest
The only place you touch more than one line is matrix builds or reusable workflows that hard-code labels. Everything else (actions, secrets, triggers) stays put.
The useful move is to duplicate the workflow and run both in parallel for a day. You want real numbers on your own builds, and the first runs on a new provider are cold-cache, so they won't reflect steady state. Compare warm.
Self-hosting is a different category of work. No label stands up a fleet, so budget for the build and the ongoing operations, not a migration afternoon.
Frequently asked questions
What is a GitHub Actions runner? The machine that executes a workflow job. GitHub-hosted runners are managed by GitHub and destroyed after each job. Self-hosted runners are machines you register and maintain yourself.
What is the difference between GitHub-hosted and self-hosted runners? GitHub-hosted: GitHub owns the hardware, zero setup, per-minute billing. Self-hosted: you own the hardware and all the operational work, no per-minute GitHub charge today, full control over the environment.
Is there a fee for self-hosted GitHub Actions runners? Not currently. GitHub announced a $0.002/min charge on self-hosted minutes in private repos in December 2025, planned for March 1, 2026, then postponed it indefinitely after community pushback. As of June 2026 it is not in effect. Some comparison pages still list it as active. It isn't.
Are third-party GitHub Actions runners safe? You are trusting a third party with your code and secrets, so vet them. Security-first providers should isolate each job in a clean ephemeral VM and publish clear security/compliance details.
What is the fastest GitHub Actions runner? It depends on your workload, so benchmark on your own build.
Do I have to rewrite my workflows to switch runners? No, moving from hosted to a third-party provider is a runs-on label change. Self-hosting is more involved because you also have to stand up and maintain the runners.
Can I run macOS or ARM builds? Yes. GitHub offers both, with macOS as its priciest tier. Several third-party providers offer Apple Silicon and ARM Linux too. Avrea runs both on M5 Max with Xcode caching.
The runs-on line is one of the easiest levers you have on CI speed, and most teams never pull it. If your builds are slow, that is the first place to look, long before you start splitting test suites.






