UPDATED IN SEPTEMBER 2026

Every build starts from scratch

Builds share nothing: every developer's machine and every CI run recomputes the same artifacts from source, over and over, because each cache dies with the process that produced it.

L1 · ASSISTEDWhat this level takes
MUSTNot met, not at this level
  • A build system is in place (default configuration is fine)
  • Builds run on each change
SHOULDExpected in practice, not required
  • Build completes (even if slowly)
  • CI runs builds on a shared queue (even if everyone waits)
EVIDENCEHow you would check
  • Build configuration file with default/untuned settings
  • CI logs showing full rebuild on every PR

What It Is

Builds share nothing: every developer's machine and every CI run recomputes the same artifacts from source, over and over, because each cache dies with the process that produced it. A developer compiles the project. A colleague pulls the same commit and compiles it again. CI checks out the same commit on a fresh container and compiles it a third time. Three identical computations, no reuse, and the only artifact that survives is the one the pipeline was asked to publish.

Some of this is invisible because it looks like normal build time. A developer's local build tool may keep a cache in their home directory, so their second build is fast and they conclude the build is fine. CI has no such luxury: its runners are ephemeral by design, so every run is a first build. The gap between "fast on my machine" and "eleven minutes in CI" is usually not a difference in hardware. It is the difference between a warm local cache and no cache at all.

This is a property of the build system, not of the pipeline. Whether runs queue behind each other, how many runners exist and who gets them first are CI/CD Pipeline questions, and this guide leaves them there. The question here is narrower and more fundamental: given the same inputs, does your build recompute the same outputs? At this level the answer is yes, every time, and no amount of runner capacity changes that - it only lets you pay for the redundant computation in parallel.

The condition is stable until agents arrive. Redundant work is affordable when builds are infrequent; the cost is real but it is spread across a working day and everybody has learned to live with it. Agent fleets remove the slack. A team that goes from a few dozen builds a day to several hundred pays the full from-scratch cost several hundred times, and the first thing that breaks is not the budget but the feedback loop: agents iterate at the speed of their slowest verification, and a cold build is the slowest verification there is.

Why It Matters

  • The same computation is paid for many times a day - identical inputs producing identical outputs, recomputed per developer and per run, is pure waste that grows linearly with team size and build frequency
  • CI is structurally slower than local development - ephemeral runners start cold every time, so CI experiences the worst case of a build that developers only ever see on a clean checkout
  • Build time becomes the ceiling on agent iteration - an agent cannot converge faster than it can verify, and a from-scratch build sets that floor regardless of how capable the agent is
  • Capacity spending papers over the problem - buying more runners makes redundant work concurrent rather than unnecessary, which is the most expensive way to not fix it
  • It hides the real bottleneck - when everything is slow, nobody can tell whether the build, the tests or the pipeline is the constraint, so optimisation effort lands more or less at random

Getting Started

  1. Measure cold and warm separately - Time a build on a clean checkout with no caches, then time an incremental build after a one-line change. The ratio is the size of the prize. Teams routinely discover their CI is paying a ten-to-one penalty that nobody had quantified because nobody had measured the two numbers side by side.
  2. Turn on the build tool's own cache first - Gradle's build cache, Go's GOCACHE, Rust's target directory and sccache, Turborepo's local cache, and BuildKit's layer cache all exist and are usually off or default-scoped in CI. Local caching is a configuration change, not a project, and it is the prerequisite for anything shared later.
  3. Find out why your build is not cacheable - Most builds that "cannot use caching" are non-deterministic: timestamps embedded in artifacts, absolute paths baked into outputs, code generation that emits a different ordering each run, or steps that read files they never declared. Build the same commit twice and diff the outputs. The diff is the list of things to fix.
  4. Make CI check out and build the way developers do - If CI uses different flags, a different toolchain version or a different working directory layout, its outputs will never be interchangeable with a developer's, which forecloses sharing before you have started. Converge the configuration now, while there is no cache to invalidate.
  5. Pick one module and prove the model - Rather than a build system migration, take the single most expensive compilation unit and make it cacheable end to end. A measured result on one module is what funds the rest; a plan for the whole repository is what gets deferred.
  6. Write down the cost you are currently paying - Multiply the from-scratch build time by the number of builds per week, and do it again at the build volume you expect once agents are in normal use. This number is the argument for the next level, and it is much larger than most teams assume.
TIP

The fastest way to see whether you have a caching problem or a slow-build problem is to build the same commit twice in a row in CI. If the second run is no faster than the first, nothing is being reused and the fix is caching. If both runs are slow and roughly equal to a warm local build, the build itself is slow and caching will not save you.

Common Pitfalls

Concluding that the build is fast because it is fast locally. A warm local cache flatters the build and hides the cost everyone else is paying. The honest measurement is a clean checkout on a machine that has never built this project, which is what CI does on every single run.

Adding cache steps to the pipeline instead of fixing the build. Hand-written save and restore steps in a workflow file, with keys invented by hand, are a caching layer built by people with no visibility into the dependency graph. They produce stale artifacts and bugs that appear only in CI. Caching correctness belongs to the build tool, which knows what each step actually consumed.

Buying capacity to hide redundant computation. More and bigger runners reduce wall-clock time without reducing work, so the cost curve keeps rising with build volume and the underlying problem is never diagnosed. This is a particularly easy mistake to make when agents arrive, because the load increase looks like a capacity problem.

Assuming the build is not cacheable without checking. "Our build is too dynamic to cache" is almost always a statement about undeclared inputs and non-deterministic outputs rather than about the domain. Both are fixable, and the fix pays off again at every later level of build maturity.

Caching artifacts that should never be reused. Test reports, coverage output, logs and timestamped bundles are run-specific. Sweeping them into whatever gets preserved between runs produces results that describe a previous run, which is worse than no caching because it is wrong rather than merely slow.

How Different Roles See It

BobHEAD OF ENGINEERING

Bob's CI bill has grown faster than his headcount since the team started using agents, and his instinct is that CI is under-provisioned - the queue is visibly long and people complain about waiting. The proposal on his desk is to double the runner pool.

Bob should ask for one number before approving it: how long a build of an unchanged commit takes on a fresh runner. If building the same thing twice takes the same time twice, the team is paying for identical computation over and over, and doubling capacity doubles the spend on that redundancy rather than removing it. Bob should redirect the first tranche of effort into making the build cacheable - determinism, declared inputs, the build tool's own cache switched on - and revisit the capacity question afterwards, when the remaining queue reflects real work. He should also be clear with himself about the timeline: this is engineering work measured in weeks, not a configuration toggle, and its return arrives as a permanently lower cost per build rather than as a one-off saving.

SarahPRODUCTIVITY LEAD

Sarah's developer survey puts build and CI wait time at the top of the frustration list for the third quarter running, but the free-text answers are contradictory. Some people describe builds as fine, others as unbearable, and she has not been able to reconcile the two.

Sarah should stop treating build time as one number. Collecting cold-build and incremental-build times, separately for developer machines and for CI, will usually explain the contradiction immediately: the people who say builds are fine have warm caches, and the people who say builds are unbearable are those whose work regularly invalidates them - plus every CI run, always. She should report the cold-build time as the headline figure, because it is what the organisation actually pays most often. Sarah should then convert it into weekly engineering hours lost to recomputation, and project the same figure at the build volume the team expects once agent use is normal rather than experimental. The projection is what moves this from a perennial survey complaint to a funded piece of work.

VictorSTAFF ENGINEER - AI CHAMPION

Victor's agents are technically working and practically slow. Each one makes a change, triggers a build, waits several minutes for a from-scratch compile, and only then finds out whether it was right. Iteration that should take a minute takes ten, and Victor has started batching agent work overnight to avoid watching it.

Victor should attack determinism first, because it is the gate on everything else and it is unglamorous enough that nobody else will. Building the same commit twice and diffing the outputs will surface embedded timestamps, absolute paths, and non-deterministic generation, and each of those is a small fix with a permanent payoff. Once outputs are reproducible he can switch on the build tool's cache in CI and demonstrate the difference on a single expensive module, which is the evidence Bob needs. Victor should also make the measurement routine rather than heroic: a job that builds an unchanged commit on a schedule and records how long it took turns cache health into a metric the team can watch, instead of something rediscovered every time somebody complains.

How This Guide Changed

What each edition changed in this guide, newest first.

  1. V1.6September 2026LATEST

    The Build System baseline is no longer about queueing, it is about recomputation: every developer's machine and every CI run rebuilds the same artifacts from source, because each cache dies with the process that produced it. Queue contention, runner counts and who waits behind whom moved to CI/CD Pipeline, which owns them. The distinction is worth the trouble because both conditions present as "CI is slow" and only one of them is fixed by buying runners.

  2. V1.3June 2026

    A quiet month for this guide. Autoscaling runner controllers settled into GitHub's mainline documentation rather than a self-hosted-runner appendix, which is roughly the shape of the fix described here, but nothing in the diagnosis of queue contention needed revising.

  3. V1.0March 2026

    Shipped to name a bottleneck teams were feeling before they had words for it: CI capacity sized for twenty humans, saturated by twenty humans each running three agents. The launch version's contribution was separating the two failure modes that usually get conflated - people waiting longer for pre-merge feedback, and agents unable to iterate at their natural speed - because they call for different fixes.

Where does your team actually sit on this?

This guide describes one level of one area. Run the assessment to place your team across all 16 areas, see which gates you have passed, and get a report you can take to your stakeholders.

Start the assessment