Infrastructure worth keeping — and kept patched.

How big a server does a build cache need? CPU, RAM and disk

You are sizing a disk, not a compute tier. The server is one small program that idles in tens of megabytes, so the question is how much cache you want to keep.

Starting sizes

vCPURAMDisk
Absolute minimum11 GBcache cap + about 5 GB for the system
Recommended start, about 5 to 20 developers plus CI1 to 22 GB25 to 50 GB SSD
Larger CI farms2 to 44 to 8 GBcache cap + about 20%

These are starting points from our deployment guide. Your build graph decides the rest. It is hard to be limited by CPU, because the busy path is reading and writing stored files, not computing.

Set a size cap

Choose how much cache you want, set it with FSCACHE_MAX_BYTES, and make the disk about 20% bigger. When the cache reaches the cap it removes the least recently used entries and never grows past it. The extra room covers file system overhead and uploads in progress.

The value is in bytes. It is easy to be wrong by a factor of 1024, so copy one:

CapFSCACHE_MAX_BYTES
10 GiB10737418240
20 GiB21474836480
50 GiB53687091200
100 GiB107374182400

Two mistakes that look like "the cache doesn't help"

What makes the disk grow

The cache grows only when a build makes an output the cache does not have yet. A build that changes nothing adds nothing. In our test, an edit inside one method added one small entry per build, about 2.5 KB. A new public method added four entries, about 11.5 KB, because the other three modules depend on it, directly or through another module, so all four were recompiled.

How we checked

After buildNo change: entries / bytesEdit inside a method: entries / bytesNew public method: entries / bytes
1 (first; the edited series include their first edit)13 / 36,09013 / 36,10113 / 36,174
213 / 36,09014 / 38,63617 / 47,725
613 / 36,09018 / 48,76833 / 93,901
1113 / 36,09023 / 61,43453 / 151,657

Three series of eleven real Gradle builds on the four-module project from Gradle build cache for a monorepo. Each series used a new empty FosterStack Cache 0.2.1 server, a fresh project copy and a new Gradle home for every build, with Gradle's local cache off. Each edit was made to a clean copy, not on top of the last. We counted the stored entries (the files in the server's blobs folder) after each build. The project is tiny, so the sizes are small; the pattern is what carries over. Not tested: a real-sized project, tests, Maven, or the cap switched on.

Put it near the runners

On bigger setups the network matters more than the processor. A small server in the same region, ideally the same network, as your CI runners beats a large one far away.

Related: Gradle and Maven setup and Jenkins and CI build cache. Full detail is in the Docker deploy guide.

Gradle and Maven setup FosterStack home