Caching Maven and Gradle Dependencies in GitHub Actions
Fast recall
Quick revision
Core answer
actions/cache to persist ~/.m2/repository for Maven or ~/.gradle/caches for Gradle between workflow runs. Cache the directory keyed by a hash of your dependency descriptor file so the cache invalidates automatically when dependencies change.Whether you understand how to optimize CI pipeline speed by avoiding redundant network calls.
Using a static cache key that never invalidates, causing stale dependencies, or caching `target/` instead of the local repository.
Mention the built-in cache support inside `actions/setup-java`, the `restore-keys` fallback for partial cache hits, and cache size limits (10 GB per repository).
Interview-ready guide
Interview answer
Caching dependencies in GitHub Actions turns a 3-minute dependency download into a 10-second cache restore. Without caching, every CI run downloads the same JAR files from Maven Central, wasting time and network on a fully deterministic operation.
Maven caching
- The
actions/setup-java@v4action caches~/.m2/repositoryautomatically whencache: 'maven'is set — the cache key is a hash of allpom.xmlfiles; adding a dependency invalidates the cache and triggers a fresh download on the next run - After the cache is populated, the next build's
dependency:go-offlinestep hits the local repository instead of Maven Central — 3 minutes becomes 15 seconds - The cache is scoped to the branch by default with a fallback to the parent branch's cache — feature branches use the main branch's cache as a starting point, preventing cold starts on new branches
Gradle caching with the setup-gradle action
gradle/actions/setup-gradle@v3caches both the Gradle home directory (wrapper, resolved plugins) and the Gradle build cache (compiled class files, task outputs) — the two-layer caching is what makes repeated Gradle builds fast in CI- The build cache is keyed by task input hash — a
compileJavatask whose inputs have not changed restores its outputs from cache and reportsUP-TO-DATEwithout recompiling; this is the Gradle equivalent ofmvn -o(offline mode) - Set
cache-read-only: trueon branches that should not push new cache entries — only the main branch's successful builds should update the shared cache; feature branches read from cache but do not pollute it with potentially stale compiled outputs
Cache invalidation
- For Maven, add
--no-transfer-progressto suppress per-artifact download progress lines that create noisy CI logs and make it harder to see which dependency changes caused a cache miss - Periodically clear stale caches using the GitHub Cache API (
gh cache list,gh cache delete) — old caches from deleted branches accumulate and can consume significant storage quota
Caching Maven and Gradle Dependencies in GitHub Actions
Direct Answer
Use actions/cache to persist ~/.m2/repository for Maven or ~/.gradle/caches for Gradle between workflow runs. Cache the directory keyed by a hash of your dependency descriptor file so the cache invalidates automatically when dependencies change.
Common Mistakes & Pitfalls
Using a static cache key that never invalidates, causing stale dependencies, or caching target/ instead of the local repository.
Check your understanding
Answer these without looking back at the article.
- How do you force-clear a stale cache in GitHub Actions?
- What is the maximum cache size per repository and what happens when it is exceeded?
- How does caching interact with matrix builds — does each matrix job get its own cache?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.