Your laptop builds reuse what CI already built
CI builds your code, and then your laptop builds the same code again from scratch. FosterStack Cache is a build cache server you run yourself: CI stores its results there, and your laptop takes them instead of redoing the work.
How it works
- You run the cache server, on your own machine or network. Both CI and every laptop point at it.
- CI builds and stores the results in it.
- Your laptop asks the cache before it builds. If the code is the same, it restores the stored result and skips the work.
It works with Gradle and with Maven. You can let only CI write to the cache and give laptops read-only access. For Gradle see let CI write, developers only read; for Maven see Maven remote build cache setup.
Does it work from a Mac laptop with Linux?
Yes, in our checks. A result stored in a Linux container was restored on a Mac, and a result stored on a Mac was restored in a Linux container. We checked this with Gradle and with Maven.
What has to match
Your laptop only reuses a result when its build inputs match CI's. In our tests these changed the cache key:
- Gradle: a different Gradle version, or a different Java version (we tested Java 21 against 27).
- Maven: a different Maven version, when plugin versions are left unpinned. Pin every plugin version your build uses, including clean, install, deploy and site, or keep the Maven version the same.
Keep those the same on laptops and CI. For what to expect after an upgrade, see we upgraded Gradle or Maven and builds got slow. If your laptop still rebuilds, see why the Gradle hit rate is low or why the Maven cache is not restoring. To set it up, see Maven remote build cache setup and the Gradle setup in the CI-writes page.
How we checked
| Stored on | Restored on | Gradle | Maven |
|---|---|---|---|
| Linux | Mac | from cache | restored |
| Mac | Linux | from cache | restored |
One small project per tool, one build per cell. Each series started on a new empty cache server, every build used a fresh project copy, and no login was set.
Gradle: four modules, Gradle 9.8.0, Java 21.0.12.1 on both sides, tested on Linux arm64 and on emulated amd64 with the same result. The runs covered the compile tasks only.
Maven: one module, Maven 3.9.9, all plugin versions pinned, Java 21.0.12.1 on the Mac and 21.0.7 on Linux.
In the runs above, the Linux side was a container on the same Mac as the cache server, and the cache was FosterStack Cache 0.2.1.
We also ran the table on two GitHub-hosted machines with release 0.2.2: Linux on amd64 and a Mac on arm64. Both used the same Java 21.0.12.1 build (unlike the Maven run above, which had 21.0.7 on Linux), Gradle 9.8.0, and Maven 3.9.9 with every plugin version pinned. First, one machine built the projects against a new cache server. We copied that server's stored files to the other machine and started a server on them. The second machine then built with an empty Gradle home and an empty ~/.m2. We did this both ways, Linux to Mac and Mac to Linux. Each time, Gradle printed > Task :compileJava FROM-CACHE and Maven printed Found cached build, restoring, and no compile task ran. This run differs from the ones above in two ways: one Gradle module instead of four, and a login was set. The run and its logs are public.
We repeated the two version checks on a GitHub-hosted Linux machine with release 0.2.2, Gradle 9.8.0 and Maven 3.10.0 and 3.9.9. Gradle with Java 27 did not restore what Java 21 stored. With unpinned plugin versions, Maven 3.10.0 did not restore what 3.9.9 stored. With every plugin version pinned, it did. The run and its log are public.
Not tested: Windows, and your own CI system (the hosted runs are GitHub's machines).