How we cut our build times in half

For a year our builds took twelve minutes. Every change to a template, every fix to a typo, waited twelve minutes before anyone could see it on the staging server. We knew it was too slow, but each step seemed to need its time.

We started by measuring. A small script wrote down when each step of the build began and ended, and after a week we had a clear picture: half of the time went into compiling dependencies that had not changed since the week before.

Caching what does not change

The fix was a shared cache. Dependencies are now built once, keyed by the hash of the lock file, and kept between builds. A build that changes only our own code skips them entirely. That alone took the build from twelve minutes to seven.

The next step was running the tests in parallel. Our test suite had grown to nine hundred tests, and they ran one after another. Split across four workers, they finish in a quarter of the time. See our testing guide for how we split them.

What we learned

Measure first. The step we were sure was slow, bundling the front end, took less than a minute. Without the numbers we would have spent weeks making the wrong thing faster.

Today a build takes five and a half minutes, and most days less. The next goal is three.