Your Self-Hosted CI Is Still on Someone Else's Meter
Stay tuned for the latest product updates, deep dives, and lessons from helping teams ship faster with InMotion Cloud.
Updated September 16, 2026 by Sean Perryman
15 Minutes to Read

The Escape That Wasn't
Most teams that self-host their CI runners did it for the same reason: the per-job pricing on hosted CI stopped making sense.
Azure DevOps is the clearest illustration. Microsoft-hosted runners come with one free parallel job and 1,800 minutes a month, and every additional parallel job costs $40 a month. For an engineering org with a few squads and a test matrix that fans out across versions and platforms, twenty parallel jobs is unremarkable. Nineteen of them are billable. That's $760 a month before anyone ships a feature, and it scales with the shape of your test suite, not with the value of your product.
So you bought hardware, stood up runners, and took the meter out of the equation.
Except go and look at your bill. On Azure DevOps, self-hosted parallel jobs are still billed: $15 a month each, beyond the first. Twenty parallel jobs (nineteen billable) is $285 a month, paid to Microsoft, for work executing on machines you bought, in a rack you pay to power and cool.
GitHub went further. On 16 December 2025 it announced a $0.002-per-minute "cloud platform charge" that would apply to self-hosted runner usage in private repositories, effective 1 March 2026. Not for GitHub's compute, for the control plane coordinating jobs that run on your own hardware.
Both of those are checkable in about a minute, and you should check them before reading further.
What "Postponed" Means
The GitHub charge never took effect.
The backlash was immediate, and the following day GitHub posted a response: "We're postponing the announced billing change for self-hosted GitHub Actions to take time to re-evaluate our approach." They acknowledged the process failure directly ("we missed the mark with this change by not including more of you in our planning") and opened a discussion thread to collect feedback. The hosted-runner price reductions announced at the same time, up to 39%, went ahead on 1 January as planned.
Most coverage treated that as the end of the story. Three details say otherwise.
It was postponed, not cancelled. That's GitHub's own word, in an official response, and the distinction isn't accidental. Nothing was withdrawn. The proposal is paused pending re-evaluation.
The rationale is still standing. GitHub was explicit about why the charge existed: "We have real costs in running the Actions control plane. We are also making investments into self-hosted runners so they work at scale in customer environments." That's a description of ongoing cost pressure, not a position they retracted. Whatever produced the December proposal is still producing it.
Nothing has replaced it. Eight months on, GitHub's billing documentation still states that Actions usage is free for self-hosted runners, and no replacement model or timeline has been announced.
It's worth putting December's two numbers side by side. GitHub said 96% of customers would have seen no increase. One developer costed the proposal at roughly $3,500 a month for their organisation. Both can be true, and the gap between them is the point: an aggregate reassurance about a customer base is not a statement about your invoice.
None of this is a claim that GitHub behaved badly. They announced, listened, and pulled back, which is more than most vendors manage. The takeaway is narrower and more durable than that:
Your self-hosted CI cost is not fixed by owning the hardware. It's fixed by your CI vendor's current pricing policy, and those are very different guarantees.
What Self-Hosting Actually Changed
None of this means self-hosting was a mistake. It was the right call, it remains the right call, and if you're running your own runners today you almost certainly shouldn't stop.
What it changed is real: hardware you control, unlimited execution minutes, no per-minute meter on the work itself, and the freedom to size machines to your actual workload instead of to someone's tier chart.
What it didn't change is the part worth sitting with.
You don't control the pricing model. You control the hardware underneath it. Those feel like the same thing right up until the month they aren't.
And you took on a second job in the trade. Somebody now owns fleet capacity planning, permanently, and that somebody is usually the two or three people you hired to build internal tooling.
Self-hosting converted a pricing problem into a capacity-planning problem, and left a residual pricing exposure behind it. That's progress. It isn't completion.
What Slow Pipelines Cost
Before getting to fleet sizing, it's worth being concrete about why anyone wants more parallel capacity in the first place.
DORA's delivery-performance research is the most useful benchmark here, and it isn't flattering. The 2025 report (drawn from nearly 5,000 practitioners) finds that only 9.4% of teams get a commit to production in under an hour, and only 16.2% deploy on demand. Read from the slow end, its lead-time bands run 28.3% at one week to one month, 13.2% at one to six months, and 2% beyond six months. 43.5% taking longer than a week. That last figure is a sum we did, not one DORA prints; the report gives the bands. Sub-hour delivery is rare, and reaching it implies CI measured in tens of minutes rather than hours.
The cost of missing that mark isn't only the wait. Research from UC Irvine on workplace interruption (Mark, Gudith and Klocke's widely cited study) puts task resumption at roughly 23 minutes. That number matters for CI specifically because of where the threshold sits. A build fast enough to wait for costs you the build. A build slow enough that you switch to something else costs you the build plus the trip back.
For the raw wait, Incredibuild's "Big Dev Build Times" survey puts developers at an average of 57 minutes a day waiting on builds. Worth flagging that Incredibuild sells build acceleration software, so read it as an interested party's figure, though it's a named survey with a stated method, which is more than most numbers in this space can claim.
The temptation is to multiply: 57 minutes, times headcount, times a loaded hourly rate, producing an alarming annual figure. I'd rather not, and you should be suspicious when a vendor does. That calculation needs a productivity-discount factor (developers context-switch during builds rather than sitting idle) and the discount factors in circulation don't come from anywhere defensible.
You have your own headcount and your own pipeline durations. The multiplication is yours to do.
Where CI Waste Actually Lives
There's a well-supported finding that 40 to 60% of typical CI spend is waste, and it's worth being precise about what that covers, because it gets stretched.
The waste itemizes to three things: test suites running sequentially that could run in parallel, workflows triggering on changes that don't require them, and missing or misconfigured caching. That's the list. It is not a claim about over-provisioned hardware, and anyone citing it that way is citing it wrong.
Here's the uncomfortable part for anyone selling infrastructure: all three are fixable without changing a single thing about who hosts your runners. Parallelize the suite. Prune the triggers. Fix the cache keys. You'll recover real money this quarter, from a vendor you're already paying.
Go do that first. It's cheaper than any migration, and it's genuinely most of the available savings.
Then notice what's still standing when you're done. Fixing your pipeline configuration doesn't change how many runners you need at 4pm on release day, and it doesn't change who sets the price of running them.
The Sizing Treadmill
Test matrices grow with squad count, not with intent.
Every team you add brings test surface with it, and matrix growth compounds: versions times platforms times configurations. Nobody decides to double the matrix. It happens between sprints, and the fleet that was correctly sized two quarters ago is quietly wrong.
That leaves you with a recurring decision instead of a solved problem. On metered infrastructure, the decision has a shape that's hard to win.
Size for peak, and you pay for capacity that sits idle most of the week.
Size for average, and you lose wall-clock exactly when wall-clock matters most: release day, incident response, the crunch before a customer deadline. The queue forms precisely when the queue is most expensive.
I could quote you a statistic here about how spiky CI load typically is. I've read several. None of them survive checking; the numbers in circulation trace back to illustrative examples on vendor blogs rather than to measurement.
So don't take mine either. Pull your own runner utilization for 3am on a Tuesday, then for 4pm on your last release day. You have better data on your own fleet than any survey I could cite you, and the gap between those two readings is the entire argument.
The question that follows is the useful one: when you last sized that fleet, was the number driven by the workload, or by what you could get approved?

Why Managed Runners Aren't the Answer Either
There's a genre of content arguing exactly the first half of this article. "Self-hosting CI runners is a trap. Self-hosted runners are a maintenance trap." If you run your own runners, you've been served these.
They're published by companies selling managed runners, and they reach the conclusion you'd expect. That doesn't make them wrong. If the thing you actually hate is the operational burden (patching runner images, debugging stuck jobs, keeping the fleet healthy) managed runners are a real answer to a real problem, and I'd rather say so plainly than pretend otherwise.
What they don't foreground is the trade. Managed runners remove the ops burden by putting you back on per-minute metering, which is the exposure you self-hosted to escape. You've swapped a capacity-planning problem for a variable-cost problem. That's a legitimate choice, but it's a swap, not a solution.
Laid out:
| Ops burden | Cost shape | |
|---|---|---|
| Hosted CI | None | Variable, per-job |
| Managed runners | None | Variable, per-minute |
| Self-hosted on metered infrastructure | Yours | Variable, per-fleet, plus residual per-job |
| Flat-fee VPC | Yours | Fixed |
The other reasonable objection is Spot. Rippling moved a 60,000-test CI pipeline onto AWS Spot instances and cut a million-dollar bill roughly in half, a genuinely impressive result and a real option. But it changes the rate, not the predictability. You still don't know next month's number, and preemption is a poor fit for release-day peaks, which is exactly when you can least afford a runner to vanish mid-job.

What It Actually Bought
Everything above is an argument about the shape of a bill. This is the measurement.
We ran it on our own Explorer plan, which is worth saying plainly: our infrastructure, our numbers, and you should read them the way you'd read any vendor's benchmark. What makes them checkable is that the workload isn't ours.
The suite belongs to SymPy, an open-source computer algebra library carrying about 13,700 tests, run across the five Python versions it supports, which is what SymPy's own CI does. Single-threaded, one version takes roughly 22 minutes; the five-version matrix comes to 107 CPU-minutes for a single commit. We split each version into twelve balanced shards, giving sixty independent jobs pulled from a queue, and ran the whole matrix on three runners, then twelve, then twenty-four, at two vCPU each, under the plan, on it, and well past it.
| Runners | Wall-clock | Utilisation | Speed-up |
|---|---|---|---|
| 3 | 27.87 min | 94% | 1.00x |
| 12 | 8.96 min | 77% | 3.11x |
| 24 | 6.37 min | 59% | **4.38x** |

Resizing between them took eighty seconds, then fifty-nine. Not eighty seconds of approval: eighty seconds of stack update.
The honest reading of that table is that eight times the fleet bought a little over four times the speed, and utilisation fell from 94% to 59% on the way. If you were hoping for the version of this article where hardware scales linearly, this isn't it.
It's worth being precise about why, because the reason is checkable and rather more useful than the curve.
At twenty-four runners the matrix finished in six minutes twenty-two. The single longest shard took five minutes forty-two. Ninety percent of that run was one job, and the other twenty-three runners spent the tail idle waiting on it.
And the interesting part is which job. Shard 11 was the slowest in all five Python versions (342, 307, 284, 254 and 242 seconds) while the fastest shards in the same run finished in sixteen to twenty-seven. A twelve- to eighteen-fold spread inside a split that was supposed to be balanced. That isn't the suite being irreducible. That's our sharding being wrong, and the run made it obvious in a way that reading the config never would have.
So the answer to "why didn't it go faster" was never buy more runners. It was fix the split, a different piece of work, on a different backlog, costing nothing but attention. We'd have bought hardware to solve a problem hardware doesn't touch, and we wouldn't have known until the invoice arrived and the pipeline was still slow.
One more result we'd rather publish than have you find. CPU-time wasn't constant across the three runs: the same sixty jobs consumed 4,736 job-seconds on three runners and 5,415 on twenty-four, about fourteen percent more work for identical tests. vCPU here is fair-share, and at twenty-four runners we were drawing double the plan's allocation, so each job ran a little slower. The failures move the same way: 98 tests hit the ten-second-per-test cap at three runners, 123 at twenty-four, out of roughly 68,000. Same tests, same cap, busier machine. Bursting past your plan is free in billing terms. It is not free in throughput terms.
The number worth taking from this isn't 4.38x. It's that finding it cost an afternoon and nothing else. We ran the full sixty-job matrix thirteen times across calibration, measurement and filming, resizing the fleet between configurations, and the bill didn't move, which is the only reason the experiment happened at all. On metered infrastructure that's a costed exercise someone signs off, which is why most teams never run it and size their fleet on a guess.
Your knee point isn't ours. Your suite shards differently, your matrix is a different shape, and your longest job is its own number. But it exists, it's findable in an afternoon, and it's the difference between buying runners that help and buying runners that idle.
The InMotion Cloud Alternative: Transparent, Predictable Pricing
The fundamental problem with metered cloud infrastructure isn't the rate. It's the shape.
Per-minute billing punishes exactly the behavior you need most: experimentation, load testing, fleet resizing, capacity planning runs. The teams that need to understand their CI workloads most are the teams least able to afford the experiments that would tell them. That's not a budget problem. It's an incentive structure that prevents optimization.
InMotion Cloud takes a different approach. Flat-fee infrastructure with soft ceilings assessed on period average, not instantaneous peak.
Take the cost variable out of fleet sizing and several things change at once. You can size for peak permanently, because peak no longer costs more than trough. The release-day queue stops being something you plan around. Resizing becomes a technical act again. Nobody needs to approve it, because no budget line moves. A traffic spike, or a new squad's test suite standing up more capacity, is an engineering event rather than a finance event.
Capacity planning goes back to engineering. The two or three people you hired to build internal tooling can spend the week building internal tooling.
And there's no meter running underneath any of it. If a release week pushes you past your plan's reference capacity, you burst. The dashboard reflects it. This month's invoice doesn't move.
That deserves precision, because "soft ceiling" is the kind of phrase that can mean anything. It isn't a cap that stops you, and it isn't a threshold that triggers overage billing. Your plan is a budget of usage-value. Every resource carries a published unit rate (so much per vCPU, per GB of RAM, per GB of storage) and your consumption is valued against it continuously. What matters is where the period average lands relative to the plan, not where the peak does.
That distinction is the whole mechanism, and it's worth seeing in real numbers.
We ran the test suite described above across a fleet that we tripled and tripled again, ending at double the plan's nominal capacity: 208% of its vCPU allowance, 244% of its RAM, 250% of its storage. Every gauge on the dashboard went red. Valued instantaneously, that fleet was running at roughly 85% of the plan's monthly budget.
Then we looked at the period average instead. 15%.
Because the burst lasted hours, not weeks. The plan is assessed on the average across the period, and a couple of hours at double capacity barely moves it. The longer the month runs, the further the two numbers pull apart. That is precisely the arithmetic a per-minute meter cannot do for you, because a meter has no concept of a period. It bills the peak, every time you touch it.
So the worst case here isn't an invoice. It's that if your baseline genuinely rises (not a release week, but a new normal) someone eventually calls to discuss whether you're on the right plan. Those are different kinds of bad month.
Which is also why this shape suits CI specifically. CI load is episodic by nature: release days, crunch weeks, then quiet stretches where the fleet does almost nothing. A model that prices the average absorbs exactly that pattern. Metered infrastructure does the opposite. It charges you most precisely at the moment you can least tolerate a queue.
Conclusion
Two things worth being straight about, because this pitch is more credible narrow than wide.
The operational burden doesn't go away. You still run the runners. You still patch them, debug them, and get paged when the fleet misbehaves. What changes is the cost shape, and therefore who has to be in the room when you resize.
And nobody can promise immunity from pricing decisions. InMotion Cloud is a vendor with pricing power, like every vendor named in this article. That isn't the claim.
The claim is narrower. There's a difference between a flat fee with a defined ceiling and a control-plane charge that can be introduced, at a per-minute rate, on workloads already running on hardware you own. One of those you can plan against.
December 2025 was a reasonably good demonstration of what the other one feels like.
Sources
- Azure DevOps Services pricing (Microsoft: Parallel job pricing, hosted and self-hosted)
- Update to GitHub Actions pricing (GitHub Changelog, 16 December 2025, including the postponement note)
- Updates to GitHub Actions pricing Discussion #182186 (GitHub's official response, 17 December 2025)
- GitHub walks back plan to charge devs for using their own hardware (The Register, 17 December 2025)
- About billing for GitHub Actions (GitHub Docs, current status of self-hosted billing)
- 2025 DORA Report: State of AI-Assisted Software Development (DORA / Google Cloud, published 23 September 2025, v. 2025.2)
- Mark, G., Gudith, D., & Klocke, U. "The Cost of Interrupted Work: More Speed and Stress." (UC Irvine)
- Incredibuild "Big Dev Build Times" survey (Vendor survey, attributed as such in text)
- LeanOps "Your CI/CD Bill Is 3-5x What It Should Be" (2026, CI waste itemization)
Sean Perryman
Technical Account Engineer
Sean Perryman is a Product Engineer at InMotion Cloud, where he helps organizations design, deploy, migrate, and support mission-critical workloads in the cloud. Working closely with customers throughout the entire lifecycle of their environments, he specializes in solving complex infrastructure challenges while ensuring platforms remain secure, reliable, and scalable.