The State of Build Times 2026
Median pipeline wall-clock by stack, where the minutes actually go inside a build, and which levers buy the most time back.
Executive summary
Build time is the most felt CI metric there is. It is the latency between a push and a green check, paid on every commit by every engineer, and unlike cost or coverage it is experienced directly: a developer sits and waits for it, many times a day. A slow pipeline does not just cost minutes; it changes behavior, discouraging the small, frequent commits that healthy delivery depends on, because nobody wants to wait fifteen minutes to validate a one-line change.
Yet most teams do not have a clear picture of where those minutes actually go, which makes every remedy a guess. Faced with a slow pipeline, the common reflex is to reach for a bigger runner, but a bigger runner only helps if the bottleneck is compute, and in most pipelines it is not. Without a breakdown of where the wall-clock is spent, a team cannot tell whether it needs more cores, a better cache, smarter sharding, or simply a warmer runner pool, so it spends money on the wrong lever.
This report benchmarks median pipeline wall-clock across common stacks and then opens up a single build to show the breakdown. The recurring and slightly surprising pattern is that setup work, dependency installs, environment preparation, and image pulls, eats a larger share of every run than the compile and test work the pipeline exists to do. The thing the pipeline is for is often the minority of the time it takes, which is precisely why bigger runners disappoint and warm caches deliver.
The good news is that the biggest slow-downs are also the most cacheable. Warm dependency and layer caches, test sharding, and right-sized runners compound into multi-fold speed-ups without rewriting a line of application code. These are configuration changes, not engineering projects, and they stack: a warm cache removes repeated installs, layer caching skips image rebuilds, and sharding parallelizes the tests, so applied together they routinely cut a cold serial pipeline by a factor of three or more.
The report ranks each lever by the wall-clock it returns and by how much effort it takes to land, so a team can attack the highest-return fixes first. It also covers the two taxes that median duration hides, cold-start queueing and flaky re-runs, because the build time an engineer actually feels is the worst case, not the median, and both of those taxes push the felt latency well above the benchmark.
End-to-end CI duration for a representative project in each ecosystem. · Source: Latchkey analysis (modeled)
Same pipeline run cold against one with warm dependency and layer caches. · Source: Latchkey analysis (modeled)
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.
Setup, not compute, is the biggest slice of most builds
Across stacks, dependency install and environment setup take a larger share of wall-clock than compile or test in a typical pipeline. The build-minute breakdown puts setup and dependency install as the single biggest slice, ahead of either the compile step or the test step, which inverts where most teams assume their time goes. The work the pipeline exists to do is often not the work that takes the most time.
This is why the bigger-runner reflex disappoints so often. A larger runner adds cores to the compile and test steps, but those are not the bottleneck; the bottleneck is a dependency install that is largely serial and network-bound, and more cores do almost nothing for it. The team pays for a bigger runner and sees a small improvement, because it accelerated the minority of the build that was already fast enough.
The first place to look for speed is therefore cutting repeated setup work, not adding compute. A warm dependency cache removes the install that dominates the breakdown, and a runner image that already carries the toolchain removes the environment preparation on top of it. The where-the-time-goes chart is the argument for attacking setup before anything else: it is the largest slice, and it is the most cacheable.
- Dependency install and setup is the largest slice of the modeled build minute, ahead of compile and test.
- Bigger runners accelerate compile and test, which are usually not the bottleneck, so they disappoint.
- Warm caches and toolchain-carrying runner images attack the slice that actually dominates.
Estimated split of wall-clock inside a typical web-app pipeline. · Source: Latchkey analysis (modeled)
Build time tracks the ecosystem, not just the project
Median wall-clock varies widely by stack, and the by-stack benchmark shows the spread clearly: Go-style fast builds at the quick end, dynamic languages like Node and Python in the middle, and compiled, generics-heavy ecosystems like Java and Rust at the slow end. A representative Rust pipeline takes several times longer than a representative Go one, and that difference is structural, baked into how each ecosystem compiles, not a sign that one team is doing something wrong.
The practical implication is that teams should benchmark against peers in their own ecosystem rather than a global average. A nine-minute Node pipeline and a nine-minute Rust pipeline are not comparable: the Node one may have room to improve while the Rust one may already be near its floor. Comparing against the wrong baseline leads teams to either chase improvements that the ecosystem will not give them or accept slowness that their peers have already solved.
A "slow" Rust pipeline and a "slow" Node pipeline are different problems with different fixes. Rust's time is dominated by compilation, so incremental compilation and compiler caches are the lever; Node's is dominated by dependency install and test spin-up, so a dependency cache and sharding are the lever. Diagnosing the stack first tells a team which lever to reach for, which is why the by-stack benchmark is the starting point rather than a curiosity.
Caching plus sharding compounds to a multi-fold speed-up
No single lever fixes a slow pipeline, but they stack, and the stacking is the whole point. The lever-payoff chart shows each optimization applied independently to a slow pipeline, and then the combination: a warm dependency cache, layer caching, and test sharding together deliver a 3.4x cut, well above any one of them alone. The levers do not overlap, so their gains multiply rather than merely add.
Each lever attacks a different slice of the breakdown, which is why they compound cleanly. A warm dependency cache removes the repeated installs that dominate setup. Layer caching skips image rebuilds that would otherwise repeat work bit-for-bit. Test sharding parallelizes the test legs so they run concurrently instead of serially. Because each targets a distinct slice, applying all three leaves almost no slow slice untouched.
The cold-versus-warm chart makes the cumulative effect concrete on a single pipeline: a cold seventeen-minute build drops to nine with a dependency cache, to six with layer caching added, and to roughly five fully warm. That is the same compounding viewed as a build rather than as multipliers, and it requires no change to application code, only to how the pipeline caches and parallelizes the work it already does.
- Caching and sharding target different slices, so their speed-ups multiply rather than overlap.
- A warm dependency cache, layer caching, and sharding together cut a slow pipeline by 3.4x.
- A cold 17-minute build drops to roughly 5 minutes fully warm, with no application-code changes.
Relative speed-up from each optimization, applied independently to a slow pipeline. · Source: Latchkey analysis (modeled)
Warm caches turn a cold build into a fast one
The cold-versus-warm benchmark isolates the single most important lever in this report: cache state. The same pipeline that takes seventeen minutes cold takes about five fully warm, a better than three-fold difference driven entirely by whether the dependencies and image layers are already present or have to be fetched and rebuilt from scratch on every run.
The reason cache state dominates is that it directly governs the largest slice of the breakdown. Setup and dependency install are the biggest part of a cold build precisely because nothing is cached, so every dependency is downloaded and every layer rebuilt. Warming the cache collapses that slice, which is why the same optimization shows up as both the biggest slice in the breakdown chart and the biggest jump in the cold-versus-warm chart: they are two views of the same effect.
The catch is that a cache only helps if it is actually warm when the job runs, which is a runner-layer property, not a pipeline-configuration property. A cache that is cold on every fresh runner, because the runner is ephemeral and nothing persisted, delivers the cold column on every run no matter how well the pipeline is configured to use it. Keeping the cache warm across runs is what turns the seventeen-minute cold build into the five-minute warm one in practice rather than only in principle.
Cold starts and queueing are a small but avoidable tax
Queue time and cold runner startup add a steady few percent to every run, shown as the smallest slice in the build-minute breakdown, and on bursty workloads it is much worse than the median suggests. A push during a quiet period starts almost immediately, but a push during a merge rush waits for capacity, so the same pipeline can feel fast at 2pm and slow at 5pm for reasons that have nothing to do with the build itself.
This tax is distinct from the others because no amount of caching or sharding touches it. A perfectly warm, perfectly sharded pipeline still waits if there is no runner free to start it, and a bigger runner does not start any faster if it is queued behind other jobs. The queue-and-cold-start slice is a capacity problem, and capacity problems need a capacity answer.
Warm runner pools are that answer. A pool of pre-started runners absorbs the spikes so jobs begin in seconds rather than waiting for a fresh instance to boot or for capacity to free up. That removes a tax that the per-pipeline levers cannot reach, which is why it belongs in the report alongside caching and sharding: it is a real slice of the felt build time, and it is solved at the runner layer rather than in the pipeline.
Flaky reruns inflate the build time teams actually feel
Median duration understates real latency because a flaky failure forces a full re-run, doubling the wall-clock an engineer waits before merging. The benchmark numbers in this report are medians, but the number a developer experiences on a bad push is the median plus a whole second run, because a spurious red check sends the pipeline back to the start. Felt build time is the worst case, not the median, and flakes are what push it there.
The crucial detail is that most of those failures are transient and pass on a clean retry: a network blip pulling a dependency, a registry timeout, a race that only shows up under load. The test code was fine; the environment hiccuped, and the re-run succeeds. That means the doubled wall-clock was not buying any signal; it was pure waste, paid because a mechanical failure was surfaced as a red check and the whole pipeline re-ran to clear it.
Auto-healing the transient failures keeps the effective build time close to the median instead of the worst case. When a step fails on a known-transient signal, a self-healing runner retries just that step on a fresh environment before the failure ever becomes a red check, so the pipeline does not restart and the engineer does not wait through a second full run. This keeps the build time a team feels aligned with the benchmark it measures, rather than spiking to double on every flake.
- A flaky failure forces a full re-run, so felt build time is the median plus a whole second run.
- Most such failures are transient and pass on a clean retry, so the doubled wall-clock buys no signal.
- Auto-healing the transient ones keeps effective build time near the median instead of the worst case.
A slow build is also an expensive one, and the same fixes cut both
Build time and build cost are the same problem viewed through two lenses, because a CI minute is billed whether it is doing useful work or waiting on a cold cache. Every minute a build spends re-installing dependencies it could have cached, or restarting after a flake it could have healed, is both a minute the developer waits and a minute the team pays for. The wall-clock levers in this report are therefore cost levers at the same time.
The relationship sharpens on the premium runner tiers. A wasted minute on Linux is cheap, but the same wasted minute on a Windows runner costs twice as much and on macOS 10 times as much, so a slow build on a premium tier wastes money at the OS multiple. Caching, sharding, and healing cut the wasted minutes, and keeping OS-agnostic work on Linux ensures the minutes that remain are billed at the cheapest rate.
The runner layer compounds both effects. A managed runner that ships warm caches and a warm pool delivers the speed-ups in this report by default rather than by configuration, and at roughly 69 percent below hosted rates, around $0.0025 per minute, the minutes that remain are cheaper too. Faster and cheaper are not a trade-off here; the same warm-cache, warm-pool, auto-healing infrastructure produces both.
Recommendations
Diagnose the breakdown before reaching for a bigger runner
Setup and dependency install, not compile and test, is the largest slice of most builds, so a bigger runner usually accelerates the wrong part. Measure where your wall-clock actually goes first, then attack the largest slice, which is almost always the cacheable setup work rather than the compute the pipeline exists to run.
Warm the dependency and layer caches
Cache state is the single largest lever in this report: a cold 17-minute build drops to roughly 5 minutes fully warm. Cache dependencies and image layers, and make sure the cache is actually warm on the runner that runs the job, because a cache that goes cold on every fresh runner delivers the cold column no matter how the pipeline is configured.
Shard tests and stack the levers
The levers compound because they target different slices: a dependency cache removes installs, layer caching skips rebuilds, and sharding parallelizes the tests. Applied together they cut a slow pipeline by 3.4x, so land all three rather than stopping at the first, since none of them overlaps with the others.
Benchmark against your own ecosystem
A "slow" Rust pipeline and a "slow" Node pipeline are different problems with different fixes, so compare your wall-clock against peers in the same stack, not a global average. Diagnosing the ecosystem tells you whether to reach for compiler caching, dependency caching, or sharding, instead of chasing gains the ecosystem cannot give.
Use a warm pool and auto-healing to kill the hidden taxes
Cold-start queueing and flaky re-runs inflate the build time teams actually feel beyond the median, and neither is touched by caching or sharding. A warm runner pool starts jobs in seconds and auto-healing clears transient flakes before they force a full re-run, keeping felt build time close to the benchmark rather than the worst case.
Outlook
Expect build time to be increasingly tracked as a first-class delivery metric over the next two years, sitting alongside the DORA measures rather than below them. As teams internalize that slow pipelines suppress the small, frequent commits healthy delivery depends on, build duration stops being an engineering inconvenience and becomes a leading indicator of delivery health that leaders watch and defend a budget for.
The fixes will continue to converge on the runner layer rather than the pipeline configuration. Warm caches, warm pools, and auto-healing are the levers that deliver the multi-fold speed-ups in this report, and all three are properties of where the build runs rather than how it is written. As managed runners ship these by default, the gap will widen between teams that get fast builds for free and teams that hand-configure each lever and still go cold on every fresh runner.
For most teams the durable takeaway is that build time is mostly a setup-and-infrastructure problem, not a compute problem, which is the opposite of the bigger-runner instinct. Diagnose the breakdown, warm the caches, shard the tests, and put a warm, auto-healing runner pool underneath, and a cold seventeen-minute pipeline becomes a warm five-minute one that is also cheaper to run. The teams that act on that will spend the period shipping faster while their peers keep buying bigger runners for the part of the build that was never slow.
Methodology
This report draws on Latchkey's analysis of aggregate pipeline timings across representative projects per ecosystem, framed against public developer surveys and the DORA research on delivery performance. Figures labeled "modeled" are illustrative estimates from representative pipeline shapes, not a primary survey, and indicate direction and magnitude rather than precise population values. Wall-clock figures assume standard two-core Linux runners unless noted and will vary with project size, test count, and cache state. Per-minute cost figures use the published hosted rates and the Latchkey managed rate of $0.0025 per minute from the shared pricing spine, roughly 69 percent below the hosted blend. 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
- DORA State of DevOps Report
- Stack Overflow Developer Survey
- GitHub - Octoverse
- JetBrains Developer Ecosystem Survey