The 2026 CI Cost Index
One headline dollar figure for what a single typical pipeline run actually costs, broken out by stack, runner size, and operating system.
Executive summary
Most engineering teams can quote their cloud bill to the dollar but cannot say what a single pipeline run costs. That gap matters because CI cost scales with the count of runs, not with the size of the monthly invoice, and the unit cost is where the leverage lives. A team that knows its per-run cost can reason about every optimization in concrete terms: this cache saves nine cents a run, that matrix change saves a dollar, this runner downgrade pays for itself in a week. A team that only sees an aggregate invoice is reduced to guessing.
This index fixes a reference point. We define the CI Cost Index as the modeled cost of one representative pipeline run, computed as billed minutes multiplied by the published per-minute rate for the stack's dominant runner operating system. The headline value is $0.42, the modeled midpoint of a typical web-application pipeline running on hosted Linux. It is deliberately a single number, the way a consumer price index is a single number, so that a team can ask one blunt question: is our average run above or below the index, and why.
Across the stacks we model, a typical run lands between roughly twenty cents and well over a dollar, and the spread is driven mostly by two levers rather than by how much work the pipeline does. The first lever is how many minutes the pipeline burns. The second, and frequently the larger, is which operating system those minutes run on. Because a macOS minute costs ten times a Linux minute, an iOS pipeline can cost more than a backend pipeline that does several times the actual computation. The index makes that distortion visible instead of letting it hide inside a blended bill.
The same model shows the managed-runner line sitting consistently below every hosted option, about 70 percent cheaper per pipeline, because the savings come from the per-minute rate rather than from running fewer minutes. That is an important distinction. Most pipeline optimizations ask the team to do less work or restructure tests, which takes engineering effort and carries risk. Moving the per-minute rate is a substitution at the infrastructure layer that leaves the pipeline untouched, which is why the runner layer, not the test suite, is usually the fastest place to drive the index down.
The strategic takeaway for 2026 is that unit cost has quietly become the live lever in CI economics. Adoption is near the ceiling, so almost every team is already paying this index many times a day. The question is no longer whether to run CI but what each run costs and how to lower it without slowing delivery. This report indexes that unit cost, decomposes where the dollars actually go inside one run, and lays out the handful of moves that shift the number most.
Billed minutes times the published per-minute rate for each stack's dominant runner OS. · Source: Latchkey analysis (modeled), GitHub Actions pricing
Same Node web-app pipeline run on progressively larger hosted runners vs managed. · Source: Latchkey analysis (modeled), GitHub Actions pricing
Email me the report
The full report is right here on this page, free. Want the link in your inbox to read later or share, plus new Latchkey reports as they drop? Drop your email and we will send it over.
Sent! Check your inbox for the report link.
No spam. Unsubscribe anytime.
The index is set by minutes and OS, not by test count
Two pipelines that run the same number of tests can differ in cost by a factor of ten purely because of the runner operating system. The CI Cost Index isolates this effect cleanly. Holding the work constant and changing only the operating system moves a typical fixed-minute run from forty-two cents on Linux to over four dollars on macOS, with Windows sitting in between at roughly double Linux. The test code did not change, the runtime did not change, only the meter rate changed.
This is the single most counterintuitive result in the index, because it inverts the instinct that expensive pipelines are the ones doing the most work. In practice the most expensive runs are frequently the ones doing modest work on a premium operating system: a handful of unit tests and a lint pass that happen to be pinned to macOS because the whole matrix was declared macOS once and never revisited. The premium meter runs the entire time, including for the OS-agnostic legs that would pass identically on Linux.
Teams chasing a lower index should therefore start with a single audit question before touching a line of test code: which legs of this pipeline genuinely require macOS or Windows, and which are there only by inheritance. Signing, packaging, and platform-specific UI tests are real reasons to pay the premium. Linting, dependency resolution, unit tests, and build steps almost never are. Pinning everything else to Linux typically moves the index more than any amount of test tuning.
- A macOS minute is 10x a Linux minute and a Windows minute is 2x, per published GitHub pricing.
- OS choice, not test count, is usually the dominant term in a single run's cost.
- Reserve premium operating systems for signing, packaging, and platform UI tests; pin everything else to Linux.
Same fixed-minute pipeline priced on each hosted OS rate vs the managed rate. · Source: GitHub Actions pricing, Latchkey rates
Bigger runners rarely pay for themselves on the index
There is a persistent assumption that a larger runner is a cheaper runner because the job finishes faster. The index shows why that assumption usually fails. Doubling cores roughly doubles the per-minute rate, so a larger runner only lowers per-pipeline cost if it more than halves wall-clock time. Most pipelines do not, because they are gated by serial setup, a single long-pole test shard, and steps that simply do not parallelize across more cores.
In our model the sixteen-core run costs over six times the two-core run for a pipeline that is not embarrassingly parallel, because the extra cores sat largely idle while the meter ran at the premium rate. The wall-clock improvement was real but modest, perhaps thirty or forty percent, nowhere near the factor needed to offset an eight-fold jump in per-minute price. The team paid for capacity the workload could not absorb.
Right-sizing beats upsizing on the index almost every time. The correct move is to match the runner tier to the genuine parallelism of the job, then attack wall-clock time through sharding and caching rather than through raw cores. A pipeline that is actually parallel can justify a bigger runner; a pipeline that is serial underneath simply pays more to wait the same amount of time.
Roughly a third of every run is non-productive cost
When the index is decomposed into where the dollars actually go inside one run, a sobering pattern emerges. Test and build compute, the work the team actually wants, is a little over half of the per-run cost. The rest is overhead: uncached dependency installs, re-runs triggered by flaky failures, and the queue plus cold-start time before the first useful step executes. None of that is the work anyone set out to pay for.
Uncached dependency installs are the largest of the three overhead slices in our model, because a fresh ephemeral runner resolves and downloads the same dependency graph on every job. Flaky re-runs come next, and they are uniquely expensive because they double a run's cost while also imposing a developer context switch that the dollar figure does not even capture. Queue and cold-start time round it out, paid silently before any billable work that the team values has begun.
The encouraging implication is that the cheapest pipeline is not the smallest one. It is the best-cached and most reliable one. Caching collapses the install slice, automated recovery for transient failures collapses the re-run slice, and a warm runner pool collapses the cold-start slice. A pipeline that does exactly the same amount of test work can land well under the index simply by removing the overhead that the index makes visible.
- Useful test and build compute is only about half of a modeled run's cost.
- Uncached installs, flaky re-runs, and cold-start time make up the rest.
- Caching, auto-recovery, and a warm pool target the overhead without touching test code.
Modeled share of per-pipeline cost across pipeline phases for a typical web-app run. · Source: Latchkey analysis (modeled)
The managed line is the lowest at every stack and size
Across every chart in this report the managed-runner line sits below every hosted alternative, and it does so for a structural reason rather than a promotional one. The managed runner moves the per-minute rate, not the minute count. Because the index is minutes multiplied by rate, lowering the rate lowers the index everywhere the rate appears, which is to say at every stack and every core count simultaneously.
That uniformity is what makes the managed line robust. A caching optimization helps the pipelines that install a lot and barely touches the ones that do not. A sharding optimization helps the parallelizable pipelines and ignores the serial ones. A lower per-minute rate, by contrast, applies to the Node app and the Python service and the iOS build and the sixteen-core monster alike. It is the one lever that does not depend on the shape of the workload to deliver.
The savings also compound with run volume in a way a single run obscures. At a few hundred runs a month the gap is a rounding error. At a few thousand runs a month, which a mid-size org crosses quickly once CI runs on every push, the same per-run gap becomes a four-figure monthly difference. The index is the unit; volume is the multiplier; the managed line is where both work in the team's favor.
Stack choice sets the floor, not the ceiling
It is tempting to read the by-stack chart as a verdict on languages, as though Go were cheap and Node expensive. The index says something more precise. Stack choice sets a floor on a run's cost through the inherent weight of its build and dependency model, but it does not set the ceiling. The ceiling is set by the operational choices layered on top: caching, runner OS, runner size, and reliability.
A Go service models cheap because it compiles fast and resolves a lean dependency graph, so its floor is low. A Node web app models higher because its install step is heavier and its test suite tends to sprawl. But a poorly configured Go pipeline on an oversized macOS runner with no cache can easily cost more than a well-tuned Node pipeline on cached Linux. The stack chose the floor; the team chose how far above it to operate.
This reframing matters for benchmarking. A team should not compare its absolute per-run cost to a different team on a different stack and conclude anything. It should compare its run cost to the modeled floor for its own stack and ask how much of the gap is operational overhead it could remove. The index is most useful as a same-stack yardstick, not a cross-stack leaderboard.
The index moves fastest at the infrastructure layer
Every lever in this report can be sorted by effort and by payoff, and when you do, a clear ordering appears. The highest-payoff, lowest-effort moves all live at the infrastructure layer rather than in application code. Switching a premium-OS leg to Linux is a one-line matrix edit. Adding a dependency cache is configuration. Adopting managed runners changes a rate without changing a test. None of these require touching the code under test.
Lower on the list are the genuinely useful but higher-effort moves: restructuring a serial pipeline to be parallel, splitting a sprawling test suite into shards, rewriting the small minority of tests that are genuinely nondeterministic. These pay off, but they cost engineering time and carry regression risk, so they are second-pass work after the cheap infrastructure wins are banked.
The practical sequence is therefore to attack the index from the outside in. Fix the meter rate and the overhead first, because they are cheap and they apply broadly, then return for the structural pipeline work once the easy reductions are captured. Teams that invert this order spend weeks refactoring tests to save what a runner-OS audit and a cache would have saved in an afternoon.
Adoption is near-universal, so the unit cost is the live lever
With CI/CD adoption around 76 percent of professional developers, almost every team is already paying this index many times a day, every working day. CI is no longer an optional practice whose cost can be deferred by simply not adopting it. It is a standing, recurring meter, and the only remaining variables are what each tick costs and how many ticks the team buys.
That universality is exactly what makes a unit-cost index the right framing for 2026. When adoption was partial, the strategic question was whether to run CI at all, and cost was secondary to the productivity gain of having it. Now that adoption is near the ceiling, the gain is already banked across the industry, and the differentiator is no longer presence but efficiency. The teams pulling ahead are the ones that treat the per-run cost as a number to manage rather than a fact to accept.
Indexing the unit cost makes that management tractable and comparable. A team can place its average run against the index, decompose the gap, and act on the largest slice first. It can set a per-run budget and alert when a pipeline change pushes a run above it, the same way it would alert on a latency regression. The index turns a vague sense that CI is expensive into a specific, defensible target.
Recommendations
Audit the matrix and pin OS-agnostic legs to Linux
Walk every job in the pipeline and ask whether it genuinely needs macOS or Windows. Reserve the premium operating systems for signing, packaging, and platform UI tests, and move linting, unit tests, and dependency resolution to Linux. Because a macOS minute is ten times a Linux minute, this single reshaping usually moves the index more than any test-level change and carries no loss of coverage.
Right-size runners to real parallelism, not to peak fear
Match the runner tier to the genuine parallelism of the job. A larger runner only lowers per-run cost when it more than halves wall-clock time, which a serial pipeline never achieves. Profile where the wall-clock actually goes, and if it is a long-pole shard rather than raw compute, shard it before you upsize it.
Cache dependencies and build outputs and measure the hit rate
Uncached installs are the largest overhead slice in a modeled run. Treat cache keys as a first-class part of the pipeline, scoped to lockfiles and toolchain versions, and watch the hit rate the way you watch test coverage. A cache nobody measures is a cache that silently stops working and quietly raises the index.
Auto-heal transient failures instead of re-running blindly
Flaky re-runs double a run cost and impose an uncounted developer context switch. Most of these failures are mechanical, a network blip or a registry timeout, and pass on a clean retry. Retrying automatically on a fresh environment removes the majority of the flaky slice from the index without touching test code or quarantining real coverage.
Move the per-minute rate, not just the minute count
The fastest way to lower the index everywhere at once is to lower the rate every minute is billed at. Managed runners apply a rate roughly 70 percent below GitHub-hosted across every stack and core count, with no change to the pipeline itself, which is why the infrastructure layer is almost always the cheapest place to move the index.
Outlook
Expect per-run cost to become a tracked metric on more dashboards through 2026 and into 2027, sitting alongside pipeline duration and flake rate rather than buried in a finance spreadsheet. As adoption stays near the ceiling, the competitive frontier shifts entirely to efficiency, and the teams that can quote their CI Cost Index and defend it will allocate compute far better than the teams that only see an aggregate bill once a month.
The decomposition in this report is also likely to harden into standard practice. Once a team sees that roughly half of every run is overhead rather than useful work, the overhead becomes a target rather than a fact of life. We expect caching, automated recovery, and warm pools to converge into a default baseline, the same way CI itself did, because each one removes a named slice of the index for a known, repeatable cost.
The structural conclusion is that the index is lowered most reliably at the infrastructure layer. Test-level work has real value, but it is slow, risky, and workload-specific. A lower per-minute rate, a warm pool, and a working cache apply uniformly and cheaply. For most teams the practical path to a lower index over the next two years is to fix the meter and the overhead first, and treat heroic test refactors as the second pass, not the first.
Methodology
This index models the cost of a single representative pipeline run as billed minutes multiplied by the published GitHub-hosted per-minute rate for the stack's dominant runner OS (Linux 0.008, Windows 0.016, macOS 0.08 per minute). OS cost multiples (Linux 1x, Windows 2x, macOS 10x) come from GitHub pricing. The managed line uses the Latchkey blended rate of 0.0025 per minute, a 70% reduction versus the blended hosted average. Per-stack and per-size billed-minute counts are Latchkey analysis (modeled) derived from typical pipeline shapes and CI adoption near 76%. Figures labeled "modeled" are illustrative estimates derived from public pricing and typical pipeline shapes, not a primary survey; figures attributed to a named source reflect that source. Pricing reflects published rates at time of writing and should be verified against current provider pricing.
Sources
- GitHub Actions - billing & pricing
- Stack Overflow Developer Survey
- GitHub - Octoverse
- AWS EC2 On-Demand pricing