← All guides

Caching Gradle and Maven dependencies in GitHub Actions

JVM builds resolve a lot of dependencies — a mid-size Gradle or Maven project pulls hundreds of artifacts before it compiles a line — and an uncached workflow re-downloads them every run. actions/setup-java caches either build tool with one option.

The one line

- uses: actions/setup-java@v4
  with:
    distribution: 'temurin'
    java-version: '21'
    cache: 'gradle'    # or 'maven' / 'sbt'

gson does exactly this — cache: 'maven' on every setup-java step across its build workflow's matrix. The key hashes your build files (pom.xml / *.gradle* and lockfiles), so the cache invalidates when dependencies actually change.

Gradle: consider the official action for more

cache: 'gradle' on setup-java caches ~/.gradle/caches — dependencies. Gradle's own action additionally manages the build cache and configuration cache, which on a large multi-module build is a second, often bigger, win:

- uses: actions/setup-java@v4
  with:
    distribution: 'temurin'
    java-version: '21'
- uses: gradle/actions/setup-gradle@v4   # dependency + build cache managed for you
- run: ./gradlew build

Rule of thumb: small/simple build → setup-java's cache: is plenty; big multi-module Gradle build → setup-gradle earns its extra step.

Maven specifics

cache: 'maven' caches ~/.m2/repository. Two habits make it behave: run with --batch-mode (no interactive noise in logs), and if you use version ranges or SNAPSHOT parents, pin them — a cache is only as stable as the resolution it caches.

JVM test suites also run long enough that a hung one is expensive: cap it with timeout-minutes. See how popular Java repos run CI →

These hide across however many workflow files you have, which is exactly why nobody sits down and fixes them. Point GitSpider at your repo and it flags which patterns apply, with the fix for each.

Scan your repo free