← All articles

The Java Developer's Disk: Cleaning ~/.m2 and ~/.gradle

Maven and Gradle cache every dependency version you have ever resolved. Where ~/.m2 and ~/.gradle sit, typical sizes, and what is safe to delete.

· Updated September 14, 2026
JavaMavenGradlemacOSStorageCache

If you’ve written Java, Kotlin, or Scala for more than a couple of years, run this before reading any further:

du -sh ~/.m2/repository
du -sh ~/.gradle/caches

20–60 GB combined is ordinary. Neither number includes the per-project build/ and target/ directories scattered across every repository you’ve cloned, which is a separate problem covered at the end.

Maven’s ~/.m2/repository: every version, forever

Maven’s local repository is a flat, global store of every artifact — every group, every version — that any project on this machine has ever resolved. There is no built-in expiry and no automatic pruning. A dependency you used for one experimental branch three years ago is still sitting there at its exact version, next to the version you actually use today.

# The heaviest groups, usually the ones you'd expect
du -sh ~/.m2/repository/org/* | sort -hr | head -20

Safe to delete entirely. Maven re-downloads whatever the next build actually needs from your configured repositories (Maven Central, plus anything in your settings.xml). The cost is your next build for each project resolving its dependency tree fresh over the network — slower once, not broken.

rm -rf ~/.m2/repository

If you want to keep it but reclaim most of the space, snapshot versions (anything ending -SNAPSHOT) are the highest-value target — they’re rebuilt constantly and old ones are almost never referenced again:

find ~/.m2/repository -name "*-SNAPSHOT" -type d

Gradle’s ~/.gradle/caches: similar idea, worse layout

Gradle’s global cache is organized by Gradle version first, then by module — which means, exactly like JetBrains IDEs, every Gradle version you’ve ever used left its own full cache behind:

ls ~/.gradle/caches/
# 7.6  8.0  8.4  8.7  8.9  modules-2  jars-9  ...

Directories named after a Gradle version (7.6, 8.4, and so on) are safe to remove if your projects have all moved to a newer wrapper version — check gradle/wrapper/gradle-wrapper.properties in your active projects if you’re unsure which versions are still in use.

modules-2 is the dependency cache proper, shared across all Gradle versions, and functions exactly like Maven’s repository: safe to delete, everything re-downloads.

rm -rf ~/.gradle/caches

Do not delete ~/.gradle/wrapper — that’s the actual Gradle distribution .zip files your projects’ wrapper scripts point at. Deleting it just means those get re-downloaded too on next build, which is harmless but slower than it needs to be; it’s not dangerous, just worth knowing it’s a separate folder from caches.

The build/ and target/ directories you’re forgetting

Both build systems also write per-project output — Gradle’s build/, Maven’s target/ — inside every repository on disk, not in a global cache location. These are the equivalent of Rust’s target/: regenerable, and only worth deleting per-project because a global find across your whole disk is the only way to catch the ones in repos you haven’t opened in months.

# Every build/ or target/ directory across your home folder, largest first
find ~ -type d \( -name "build" -o -name "target" \) -not -path "*/node_modules/*" -exec du -sh {} \; 2>/dev/null | sort -hr | head -20

Delete individually once you’ve confirmed each one sits next to an actual pom.xml or build.gradle — the same filenames show up in non-Java projects too (Rust’s target/ is the most common collision), so don’t blanket-delete without checking.

What’s actually safe here, summarized

LocationWhat it isSafe to delete?
~/.m2/repositoryGlobal Maven dependency cacheYes, fully regenerable
~/.gradle/caches/<old-version>Per-Gradle-version cacheYes, if that version is unused
~/.gradle/caches/modules-2Global Gradle dependency cacheYes, fully regenerable
~/.gradle/wrapperActual Gradle distributionsLeave it — re-downloads are slow, not dangerous
<project>/build, <project>/targetPer-project build outputYes, per project

DevCruft, the free developer-focused Mac app we’re building, is intended to find both global caches and every stray build//target/ directory across your disk in one scan, ranked by size and last-modified date, so you’re not writing find one-liners by hand. Until it’s ready, copy the commands above — they’re free and they work. You can join the waitlist to hear when it launches.

For the rest of the language-ecosystem caches, see the section on Rust, Go and Python in the full storage guide, or the dedicated Rust, Go and Python cache cleanup guide.

A free app for this is on the way.

We’re building DevCruft to find every cache in guides like this one and show what each costs you. Join the waitlist to hear when it launches.

One email at launch, nothing else. Ask us any time to remove you. Privacy policy