The Ledger

ENGINEERING

How we cut build times in half without changing the stack

Every team has a familiar moment in the afternoon when a small change turns into a long wait. The test suite starts, the fans spin up, and the next useful thought is postponed until the pipeline finishes. Our build was not broken, exactly. It was just slow enough to shape the way we worked.

We assumed the answer would be dramatic: a new tool, a different bundler, a wholesale rewrite of the jobs that had accumulated over years. Instead, the largest gains came from treating the build like a product surface. We made the delays visible, named the expensive steps, and removed the uncertainty around what happened between commit and deploy.

Start by measuring, not guessing

The first week was deliberately unglamorous. We added timestamps to each stage, saved cache hit rates, and compared cold runs with the incremental path most engineers used every day. The numbers quickly challenged our instincts. A task everyone complained about was noisy but inexpensive, while a quiet asset step consumed nearly a quarter of the total time.

The breakthrough was not a clever shortcut. It was agreeing that a build should explain itself before we tried to make it faster.

Once the shape of the delay was clear, the fixes were small and cumulative. We tightened cache keys, split independent checks into parallel lanes, moved rarely changed generated files out of the hot path, and stopped running integration fixtures for packages that had not changed. None of those choices altered the stack. Together, they changed the rhythm of the day.

The final result was a median build time that fell from just over twenty minutes to under ten. More importantly, engineers trusted the pipeline again. When a build slowed down, the dashboard showed why, and when a new step was proposed, its cost was part of the design discussion from the start.