On December 16, 2025, GitHub announced that self-hosted Actions runners — the ones teams stand up specifically to get off metered CI compute — were about to get a meter of their own: $0.002 per minute, starting March 1, 2026. Less than 48 hours later, after a community discussion thread filled with objections, GitHub postponed it. As of today it still hasn't come back, and there's no announced replacement.
That whiplash is the headline. The part worth sitting with is what the charge was actually billing for, because it wasn't the compute — teams already own that. It was the orchestration: the webhook receipt, the job queue, the dispatch to your runner. Self-hosting the machine that runs your build never got you off GitHub's control plane, and this is the moment that became visible.
What $0.002/Minute Would Have Actually Cost
The charge scaled linearly with self-hosted runner minutes in private repositories, regardless of where those runners lived — AWS, GCP, on a rack you own. At the announced rate:
| Monthly self-hosted runner minutes | Monthly charge |
|---|---|
| 10,000 | $20 |
| 50,000 | $100 |
| 100,000 | $200 |
| 500,000 | $1,000 |
Put a real workload against that table: a team running 300 CI jobs a day at an 8-minute average is 2,400 minutes a day, or roughly 72,000 minutes a month — interpolating the table, that's about $144/month, on top of whatever they'd already spent building and maintaining the self-hosted runner fleet in the first place. It's not a business-ending number for most teams. It is a number that didn't exist the day before, attached to infrastructure teams already owned outright, billed by a party that doesn't run any of it.
Two categories were carved out entirely: public repositories, and GitHub Enterprise Server customers running Actions entirely on their own infrastructure. Everyone else who'd already invested in self-hosted runners specifically to avoid per-minute billing would have started paying per-minute billing anyway.
GitHub's own numbers, released alongside the postponement, put the blast radius at 4% of customers seeing any bill change at all, 85% of those seeing a decrease (from the same-cycle 39% cut to GitHub-hosted runner prices), and individual accounts facing a median increase under $2/month. Read generously, that's "almost nobody was affected much." Read as the audience that showed up in the backlash thread, it's a smaller number of unusually vocal, high-usage self-hosted shops — exactly the platform-engineering teams who'd done the work to get off metered compute, discovering the meter followed them home anyway.
The Cut-Then-Backlash Pattern
This wasn't an isolated pricing update. It landed as part of a package: GitHub cut GitHub-hosted runner prices by up to 39% on January 1, 2026, following a backend re-platform of the hosted-runner fleet, then announced the self-hosted charge two weeks later in the same December 16 changelog post. The self-hosted line item read almost like a bundled a la carte fee riding alongside a genuine price cut — the kind of framing where one number is designed to make the other look smaller.
GitHub's stated rationale was explicit about what the charge covered: "self-hosted runner customers leveraged GitHub Actions' infrastructure at no cost, meaning maintenance expenses were subsidized by GitHub-hosted runner pricing." In other words, the charge was never framed as a compute fee — GitHub doesn't run your self-hosted compute. It was a fee for the scheduling and dispatch layer that decides when your runner picks up a job, which every self-hosted runner still depends on GitHub to provide.
The retreat was just as telling. GitHub's postponement notice didn't defend the pricing logic; it conceded process: "We missed the mark with this change by not including more of you in our planning." That's a company acknowledging it under-tested how a core-infrastructure audience would react to a fee on the one thing they'd already paid to escape — not a company walking back the underlying economics.
Your Runner Is Self-Hosted. Your Trigger Isn't.
Here's the mechanism the whole episode surfaces: a self-hosted GitHub Actions runner doesn't listen for a git push directly. Whether it's a single VM running the actions-runner agent or a fleet managed by Actions Runner Controller on your own Kubernetes cluster, it registers itself with GitHub's Actions service using a short-lived registration token, then long-polls GitHub's job queue for work assigned to it. The push event, the workflow-file evaluation, the job scheduling, the "here's your job" dispatch — all of that happens inside GitHub's infrastructure before your runner ever sees a checkout step. You own the machine executing the build. You do not own the thing deciding a build should happen, and you can't point that registration token at any queue but GitHub's.
That's a distinction platform teams routinely skip past when they self-host CI "for cost control." Self-hosting the compute genuinely removes GitHub-hosted-runner minute billing. It does nothing about the control-plane dependency the March 1 charge was aimed squarely at — because that dependency was never about where the minutes ran, it was about who orchestrates them. A metered self-hosted-runner fee is really a metered control-plane-access fee wearing a compute-pricing costume, and it can come back in a different shape (org-level API-call limits, a webhook-throughput tier, a "premium orchestration" SKU) without anyone having to reintroduce the exact line item that got walked back.
It's also worth naming the security mirror of the same dependency: self-hosted runners have to accept jobs dispatched from GitHub's queue by design, which is exactly the property threat researchers have flagged as a backdoor risk when a runner's registration token or webhook secret leaks — an attacker who can queue a job against your runner gets code execution on infrastructure you thought you'd walled off. Owning the orchestration layer isn't just a billing question; it's the same trust boundary GitHub's control plane sits inside either way.
What Actually Owning the Trigger Buys Back
The alternative isn't a nicer self-hosted runner — it's removing GitHub Actions' control plane from the loop entirely, which means replacing both halves: the thing that receives the push event, and the thing that runs the build.
- Gitea/Forgejo Actions run the whole stack — git hosting, webhook receipt, job scheduling, and runner dispatch — on infrastructure you operate end to end. There's no GitHub Actions control plane to depend on because there's no GitHub Actions anywhere in the path.
- Woodpecker CI stays compatible with a GitHub-hosted repo but takes over everything downstream of the push: it registers its own webhook against your repo, receives push events directly from GitHub's webhook delivery (not Actions' job queue), and dispatches to runners you control. GitHub still hosts your code; it never touches your CI orchestration.
- A hand-rolled webhook receiver is the same idea with no framework: a small service listening for GitHub's
push/pull_requestwebhook payloads, verified against a shared secret, that hands the ref straight to your own build runner. No Actions workflow YAML is ever evaluated — nothing runs through GitHub's scheduler at all.
All three share the same property the self-hosted-Actions-runner setup never had: the decision "this push means run a build" happens on infrastructure you control, not infrastructure GitHub bills separately from your compute.
This is close to the model a self-hosted, git-push PaaS runs by construction rather than as a CI migration project. Bex.co's own build pipeline works this way: a git push lands on infrastructure you own, a webhook you control (not a third-party Actions control plane) triggers the build, and the resulting container runs on the same Cluster API-managed machines serving the app — no per-minute orchestration meter sitting between your commit and your deploy, because there's no separate orchestration vendor in the path to meter.
The Charge Is Postponed, Not Resolved
Self-hosted runners are free today, with no committed timeline for whether or when a version of this charge returns. That's worth remembering the next time "we self-host our CI" gets marked off a cost-risk list — the compute line item was already handled, but the control-plane line item was never actually eliminated, just unbilled. The March 2026 episode is a preview of what happens when a platform decides to bill for the part of "self-hosted" you don't actually control. Teams that want the compute-savings story to also be a lock-in-savings story need to own the trigger, not just the runner.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with your own webhook triggering your own build, no third-party orchestration meter in between. Star the repo on GitHub or deploy your first app today.