
Migrate BuildJet to Tenki Runners: Labels, Cache, Costs
On December 16, 2025, GitHub announced a $0.002-per-minute "cloud platform charge" for all GitHub Actions workflows, including those running on self-hosted runners. Two days later, they reversed course. The charge that was supposed to hit self-hosted runner users on March 1, 2026 is now "postponed to re-evaluate."
That's good news in the short term. But "postponed" doesn't mean "cancelled." If you're running self-hosted runners at any meaningful scale, the smartest thing you can do right now is figure out what the charge would actually cost you, and whether your current setup is worth defending.
The original announcement bundled two changes together. First, GitHub-hosted runner prices dropped by up to 39% across all runner sizes, effective January 1, 2026. That part stayed. Second, a new $0.002/minute charge would apply to all Actions workflows, including self-hosted runners on private repos. For GitHub-hosted runners, this fee was already baked into the reduced rates. For self-hosted runners, it was a net-new cost.
GitHub justified this as covering the "Actions control plane" — the job scheduling, log ingestion, artifact storage coordination, and workflow orchestration that runs on GitHub's infrastructure regardless of where the runner executes. The announcement noted that since August 2025, all Actions jobs run on a re-architected backend handling 71 million jobs per day, up from 23 million in early 2024.
The community response was immediate and hostile. The GitHub Community discussion hit 64 top-level comments and 66 replies within days. The most-upvoted comment (130 upvotes) put it bluntly: "Don't charge them the same per minute price as your own runners, that is just anti-competitive. We are already paying for the privilege of using the 'control plane' by paying for our Github accounts."
Within 48 hours, GitHub posted an update: "We're postponing the announced billing change for self-hosted GitHub Actions to take time to re-evaluate our approach." The hosted-runner price reductions went ahead as planned.
Three complaints dominated the feedback, and they're worth understanding because they'll shape whatever GitHub proposes next.
Per-minute billing penalizes slower hardware. One volunteer organization running donated older hardware pointed out that slower builds directly mean higher costs under per-minute pricing. You'd essentially pay more for the privilege of using less capable machines. That's backwards.
Enterprise customers felt they already pay for the control plane. GitHub Enterprise Cloud runs $21/user/month. Teams with hundreds of seats saw the control-plane charge as double-dipping. Many use self-hosted runners not by choice, but because compliance requirements force them off GitHub-hosted infrastructure.
The pricing doesn't reflect actual resource consumption. A flat per-minute rate ignores that control-plane costs vary wildly. A runner that emits megabytes of logs per minute costs GitHub more than one that runs quietly. Several commenters suggested alternative billing models: per-job charges, log-volume quotas, or tiered free allowances for self-hosted usage.
GitHub didn't say "we've decided not to charge for self-hosted runners." They said they need more time to get the model right. The feedback discussion they opened is collecting input on what a fair pricing model would look like. That strongly suggests a revised charge is coming, possibly with a different billing unit (per-job instead of per-minute), tiered free quotas, or enterprise carve-outs.
The best use of this window is to get your actual numbers. Most teams I've talked to don't know their monthly runner minutes within an order of magnitude.
Start with your GitHub usage report. Go to your organization's billing settings and download the detailed Actions usage CSV. This gives you per-workflow, per-repository minute counts. If you don't have access, the REST API can pull workflow run durations programmatically.
Here's the quick math at the originally proposed rate:
Monthly self-hosted minutes × $0.002 = Monthly platform charge
Examples:
10,000 minutes/month → $20/month
50,000 minutes/month → $100/month
250,000 minutes/month → $500/month
1,000,000 minutes/month → $2,000/monthFor a mid-size engineering org running 50,000 self-hosted minutes per month, that's $100. Not catastrophic. But for a company running a million minutes across dozens of repos with long integration test suites, $2,000/month is real budget that wasn't there before.
The number that matters most isn't the total — it's the ratio of self-hosted minutes to GitHub-hosted minutes. If 90% of your Actions usage already runs on GitHub-hosted runners, the self-hosted charge is a rounding error. If you're 100% self-hosted across a large fleet, it's the only cost that changed.
To put the $0.002/minute number in context, here's how it stacks up against alternatives for a standard 2-core Linux runner:
The key insight: if the platform charge comes back in any per-minute form, every third-party runner service built on GitHub Actions gets more expensive too. Only a full migration away from GitHub Actions entirely (to GitLab CI, Jenkins, Dagger, etc.) would avoid it completely.
Whatever the final pricing looks like, fewer minutes means lower bills. These optimizations are worth doing regardless.
Most teams cache dependencies but skip build artifacts, compiled outputs, and Docker layers. A well-configured actions/cache setup with hash-based keys for your lockfiles, build outputs, and test fixtures can cut 30-50% off typical CI times. If you're running Docker builds, enabling BuildKit layer caching or pushing cache to a registry saves even more.
Path filters (on.push.paths) are the simplest optimization most teams still don't use. If your monorepo has 10 services and a docs-only change triggers all 10 build pipelines, you're burning 9x the minutes for no reason. Combine path filters with concurrency groups that cancel superseded runs when a new push lands on the same branch.
Running test suites sequentially on a single runner when you could shard across 4 runners doesn't save minutes under per-minute billing. Total wall-clock time goes down, but billable minutes stay the same (or go up slightly due to overhead). Under per-minute pricing, the goal is reducing total minutes, not wall-clock time. That might mean consolidating jobs that currently run in parallel but have short runtimes, eliminating the per-job startup overhead.
If you have multi-hour integration or load-test suites running as Actions jobs, those are prime candidates for extraction. An Actions job that triggers a test run on external infrastructure (and just polls for results) uses minutes only for the trigger step, not the full test duration. This is already common practice for GPU workloads and heavy simulation jobs.
If your projected cost under $0.002/minute is under $200/month, don't overthink it. Keep running self-hosted, take the easy caching and path-filter wins, and wait for GitHub's revised announcement.
If you're looking at $500+/month and you're running self-hosted primarily for cost savings (not compliance), this is a good time to benchmark GitHub's new hosted-runner rates. The January 2026 price cuts made larger runners significantly cheaper. A 16-core Linux runner is now $0.042/min. If your self-hosted 16-core machines are old enough that builds take 2-3x longer than they would on modern hardware, hosted runners might already be cheaper even without any platform charge.
If you're self-hosted for compliance or security reasons, you don't have the option to move to hosted runners. Focus your energy on minute reduction and make sure your finance team knows the range of possible outcomes. The worst case is the charge returns at $0.002/min as originally proposed. The best case is a more generous model with free tiers or per-job billing. Build your budget around the midpoint.
The original announcement wasn't just about pricing. GitHub also committed to several self-hosted runner improvements that are still on the roadmap:
These improvements are relevant to the pricing conversation. If GitHub delivers meaningfully better self-hosted runner tooling, a control-plane charge becomes easier to justify. If the improvements stall (as several community members predict, citing a five-year-old open issue on ephemeral runner scaling), the community resistance will be even stronger.
Tags
Recommended for you
What's next in your stack.
GET TENKI