Rust caching on CircleCI using sccache

If you are working in a team that’s writing Rust code and your crates have a good amount of dependencies, you have probably noticed that the Rust compilation phase takes a non-trivial amount of time in comparison to actually running your tests: it is indeed one of the top recurring complains that gets reported to the language team.

In a CI environment, it gets worse as the testing container starts building pretty much from scratch and everything gets recompiled. One way to alleviate that problem is to cache Rust compiled intermediate objects: most blog posts recommend to cache the Rust target folder in order to reduce that compilation time. This approach has one major problem as currently cargo does not do any kind of garbage collection on that folder: new versions of dependencies, dependencies compiled with different versions of Rust etc. Everything stays. This leads to huge target folders, in my case it was 20GB at worse.

Even worse, the bigger this cached folder gets, the longer it takes for CircleCI to restore that cache. It took up to 2 or 3 minutes in certain instances to restore the cache on a 12 minute job!

You could delete that directory every once in a while with an arbitrary heuristic, however let me show you a different way.

Using sccache

sccache is a compiler wrapper that caches artifacts created by a compiler such as rustc or even gcc. It is well known in the Mozilla “circles” but it could get more publicity outside of them, hence this blog post.

One of the great things about this tool is that the cached artifacts end up in a folder that can be configured with a maximum size and an LRU cleaning algorithm will keep the most relevant compiled artifacts.

So here is an “sccache + Rust hello world” CircleCI config.yml:

Using this configuration, the size of the CircleCI Rust cache can be kept under control and your builds can be fast again!