Can several projects share one build cache server?
Yes, several projects can use one FosterStack Cache server. In our runs they shared the results of identical work and could read each other's results. If a group must not see another group's results, give that group its own server.
The short answer
- Different code did not clash in our runs. Project B's own compile found nothing stored, so it ran and stored its own entry next to project A's.
- Identical work is shared. A copy of project A in another folder restored A's compile result. Project B also restored one entry from A: the compiled build script. Both build files contain the same text, so the result is the same. That reuse is harmless.
- One login reaches every project, which is a warning, not a feature. The login that B's builds used also fetched A's entry, so anyone with it sees every project's results. The read-only login read both, and its write got a
403. - One size cap covers every project. With a small cap, B's store pushed out A's entry, and a copy of A pushed B's out again.
- Separate servers kept teams apart in our runs. Team 2's server restored nothing from team 1's. Each team's login got a
401on the other server.
What to do
Our advice, not a test result:
- One server is fine when everyone may see everyone's results. Many repos in one company often fit. Two repos that build the same thing can reuse each other's results.
- Use one server for each group that must not read another group's results. Each server has its own data folder and logins.
- Treat everything in the cache as readable by anyone with a login. Do not rely on a project name to hide it.
- Give CI the read-write login and everyone else the read-only one. See let CI write and developers read and can someone poison our shared build cache.
- Size the cap for all projects together. See how big a server a build cache needs and how the size limit works.
Gradle and Maven builds can use the same server too. See one build cache server for Gradle and Maven.
How we checked
FosterStack Cache 0.2.1 and Gradle 9.8.0 with Java 21 on a Mac (arm64), one machine. Project A has three classes, project B has four different ones, and project C is an exact copy of A in a different folder. Each build ran compileJava and jar with a new Gradle home, Gradle's --no-daemon flag and the local build cache off. The cache address and login reached the build only as environment variables. All logins were made up for the test. Each row is one run.
One server, no size cap. The same read-write login for all three builds.
| Build | Compile task | Entries on the server afterwards | Restored from the server |
|---|---|---|---|
| A | Ran | 2 | Nothing |
| B, different code | Ran | 3 | 1: the compiled build script |
| C, a copy of A in another folder | FROM-CACHE | 3 | 2: A's compile result and the build script |
The jar task ran in every build, so it is left out of the rows. The key of A's compile result was the same in the copy as in A, so folder names do not matter here.
Direct requests to the same server. The key is the request path. The docs say the whole request path is the key, and we found no project or namespace setting in them.
| Request | Answer |
|---|---|
| A's compile key, with the read-write login | 200, 1,659 bytes |
| B's compile key, with the same login | 200, 1,803 bytes |
| Both keys, with the read-only login | 200 each |
| A write with the read-only login | 403, entries stayed at 3 |
| A's key with no login, or a wrong password | 401 |
| A project name in front of the key | 404 for both keys |
| Builds of A and B with the read-only login and pushing off | Each restored its compile result |
Two servers, one for each team. Each has its own data folder and logins.
| Build | What happened |
|---|---|
| A on team 1's server | Ran and stored 2 entries |
| C on team 1's server | Compile result restored |
| C on team 2's server, sending team 1's login | 401, the build warned, switched the remote cache off for the rest of that build, and ran everything |
| C on team 2's server, with team 2's login | Restored nothing and stored 2 entries |
| The same build again on team 2's server | Compile result restored |
Each team's login got a 401 on the other team's server when we asked for A's key directly.
One small size cap. A server with a 5,000-byte cap, where A's two entries take 4,472 bytes.
| Build | Compile task | Evicted so far | Entries afterwards |
|---|---|---|---|
| A | Ran | 0 | A's compile result, the build script |
| B | Ran | 1 | B's compile result, the build script |
| C, a copy of A | Ran | 2 | A's compile result, the build script |
| B again | Ran | 3 | B's compile result, the build script |
The cap belongs to the server, not to a project. The compile entry of the project that built last stayed. So did the shared build-script entry. This cap is far smaller than a real one. We only checked that the cap is shared.
Limits: Gradle only, three small projects, one run of each case on each machine. We did not test Maven, many projects building at once, or real project sizes.
Second run: Linux, 0.2.2
The run above was on a Mac with 0.2.1. We ran it again on a GitHub-hosted Linux machine with FosterStack Cache 0.2.2, Gradle 9.8.0 and Java 21, with three small projects of our own written in the same shape.
- One server: the rows matched. A ran and left 2 entries. B ran, restored the compiled build script and left 3. The copy C restored A's compile result and the build script.
- Direct requests, reads: A's and B's keys answered
200to the read-write login and to the read-only login. - Direct requests, writes and bad logins: a write with the read-only login got
403, and the entry count stayed at 3. No login or a wrong password got401. A project name in front of the key got404for both keys. - Builds of A and B with the read-only login and pushing off each restored their compile result.
- Two servers: team 1's login on team 2's server got
401. That build compiled again, and nothing was stored on or restored from team 2's server. With team 2's login the build stored 2 entries and restored nothing, and the same build again restored its compile result. For A's key, each team's login got401on the other server, in both directions. - The small cap: the same 5,000-byte cap. A's two entries took 4,025 bytes here and 4,472 on the Mac. After the four builds the server had evicted 0, 1, 2 and 3 entries, and after each of the last three the compile result of the project that built last was on the server while the other was not.
- Single entries were smaller: A's compile result was 1,211 bytes and B's 1,294 (on the Mac, 1,659 and 1,803).