skip to content

Dependency Cache

The modules-2 dependency cache under GRADLE_USER_HOME, --refresh-dependencies, and offline resolution. Interviewers ask because wiping the cache is the common superstition and rarely the actual fix.

on this pageshow

questions

5

Where does Gradle store downloaded dependencies, and what is the purpose of that cache?

level: juniorimportance: must knowfreq 60%

answer

  1. GRADLE_USER_HOME/caches/modules-2
  2. default ~/.gradle
  3. global, shared across projects + versions
  4. metadata + artifacts stored separately
  5. not the build cache

basics

~10 s

Gradle stores downloaded artifacts and metadata under GRADLE_USER_HOME/caches/modules-2 (default ~/.gradle). The cache avoids re-downloading the same dependency on every build, speeding things up and enabling offline reuse.

solid answer

~40 s

Resolved dependencies live in the **global dependency cache** at `GRADLE_USER_HOME/caches/modules-2` (default `~/.gradle`, overridable via the `GRADLE_USER_HOME` env var or `-g`). It is shared across **all** projects and Gradle versions on the machine, so an artifact downloaded once is reused everywhere. The cache stores both the binary artifacts (jars, etc.) and the resolved metadata (POMs, Gradle Module Metadata) separately, keyed by module coordinates and content hashes. Gradle uses SHA checksums and a local file lock so concurrent builds can safely share it. Because it is global, it is not part of any project directory and should not be checked into version control. Clearing it (deleting the folder) forces a full re-download on the next build.

code

bash · 8 lines
bash
# Default cache location
ls ~/.gradle/caches/modules-2/files-2.1/

# Override GRADLE_USER_HOME (e.g. on CI)
export GRADLE_USER_HOME=/ci/.gradle
./gradlew build
# or per-invocation:
./gradlew -g /ci/.gradle build

go deeper

for a junior

Know the default path (~/.gradle / caches/modules-2) and that it avoids re-downloading.

for a middle

Explain GRADLE_USER_HOME override, global sharing across projects/versions, and metadata-vs-artifact separation.

for a senior

Discuss concurrency safety, checksums, and why it shouldn't be in VCS but should be a CI cache layer.

for a principal

Frame cache strategy across a CI fleet: shared/seeded GRADLE_USER_HOME, restore keys, and isolation tradeoffs vs. cache poisoning.

## What the dependency cache is When Gradle resolves a configuration, it must obtain two things for every module: the **metadata** (which describes the module's coordinates, dependencies, and variants — a Maven POM or a Gradle Module Metadata file) and the **artifacts** (the actual jars/aars/zips). Downloading these from a remote repository on every build would be slow, so Gradle keeps a persistent local copy in the **dependency cache**. ## Where it lives The cache sits under **`GRADLE_USER_HOME`**, which defaults to **`~/.gradle`** (`%USERPROFILE%\.gradle` on Windows). The dependency cache specifically is **`GRADLE_USER_HOME/caches/modules-2`**. You can move `GRADLE_USER_HOME` with the environment variable of the same name or the `--gradle-user-home`/`-g` command-line flag. Key properties: - **Global / shared.** It is not per-project. Every build on the machine, regardless of Gradle version, reads and writes the same `modules-2` directory. A jar fetched by project A is reused by project B for free. - **Metadata and artifacts are stored separately**, each keyed by module coordinates plus a content hash, so identical content is deduplicated. - **Concurrency-safe.** Gradle uses checksums and file locks so multiple builds (even parallel ones) can share the cache without corruption. - **Not VCS material.** Because it is large, machine-local, and reproducible, you never commit it. ## Why it matters The cache is what makes warm builds fast and is the foundation for **offline builds** (`--offline`) — if everything you need is already cached, you can build with no network at all. It also underpins reproducibility: once resolved, the same versions are reused until you explicitly refresh. ```bash # Inspect the cache layout ls ~/.gradle/caches/modules-2/files-2.1/ # Move the cache for CI GRADLE_USER_HOME=/ci/gradle-home ./gradlew build ``` Do not confuse this with the **build cache** (`caches/build-cache-1`, task outputs) or per-project `.gradle/` directories — those are different mechanisms.

  • Should the dependency cache be committed to version control?
    No. It is machine-local, large, and fully reproducible from the repositories. Commit it and you bloat the repo and risk stale/incompatible binaries. On CI you instead persist/restore GRADLE_USER_HOME as a CI cache layer.
  • How is the dependency cache different from the build cache?
    The dependency cache (caches/modules-2) stores downloaded external artifacts and metadata. The build cache (caches/build-cache-1, or a remote build cache) stores reusable outputs of @CacheableTask tasks (compilation, etc.). Different keys, different purpose.

saying these in an interview costs you the question

  • Saying dependencies are cached inside the project's .gradle/ directory (that holds per-project incremental state, not the shared artifact cache).
  • Confusing the dependency cache with the build cache.
  • Claiming the cache is per-Gradle-version isolated — modules-2 is shared across versions.

context

open as a page

What does running Gradle with --offline do, and what are the prerequisites for it to succeed?

level: middleimportance: must knowfreq 45%

basics

~10 s

--offline tells Gradle never to access the network during a build; it resolves everything from the dependency cache. It only succeeds if every required metadata and artifact is already cached, otherwise the build fails.

open as a page

What does the --refresh-dependencies flag do, and when would you use it?

level: middleimportance: must knowfreq 55%

basics

~10 s

--refresh-dependencies tells Gradle to ignore cached metadata TTLs and re-check every dependency against the repositories, re-downloading metadata and any changed artifacts. Use it when a SNAPSHOT or dynamic version seems stale.

open as a page

How does Gradle decide when a cached SNAPSHOT or dynamic version is stale, and how can you control that freshness window?

level: seniorimportance: should knowfreq 35%

basics

~10 s

Gradle caches changing modules (SNAPSHOTs) and dynamic version listings with a time-to-live, 24 hours by default. You tune it per-configuration with resolutionStrategy.cacheChangingModulesFor and cacheDynamicVersionsFor, or override once with --refresh-dependencies.

open as a page

How would you design dependency-cache handling across a CI fleet for fast, reproducible builds?

level: principalimportance: should knowfreq 25%

basics

~10 s

Persist and restore GRADLE_USER_HOME (the modules-2 cache) as a CI cache keyed on lockfiles, keep release builds on fixed/locked versions, and use --offline once the cache is warm to make builds fast and network-independent.

open as a page