Go GOPATH & Module Cache Taking Up Too Much Disk Space on Mac?

Your Go module cache, build cache, and old toolchains could be eating 10-30GB. Here is exactly how to find and clean them.

Table of Contents

1. Full Go Disk Space Audit

Before cleaning anything, run this complete audit to see where your Go disk space is going:

# Go environment paths
go env GOPATH GOMODCACHE GOCACHE GOROOT

# Module cache (downloaded dependencies)
du -sh $(go env GOMODCACHE) 2>/dev/null

# Build cache (compiled objects)
du -sh $(go env GOCACHE) 2>/dev/null

# GOPATH (legacy workspace + installed binaries)
du -sh $(go env GOPATH) 2>/dev/null

# Go installation itself
du -sh $(go env GOROOT) 2>/dev/null

# Old Go versions (if using Homebrew)
du -sh /opt/homebrew/Cellar/go* 2>/dev/null
du -sh /usr/local/Cellar/go* 2>/dev/null

# Homebrew Go version manager (goenv) if applicable
du -sh ~/.goenv/versions 2>/dev/null

# Total estimate
echo "=== TOTAL GO DISK USAGE ==="
du -sh $(go env GOPATH) 2>/dev/null
3-15 GB
Module Cache (go/pkg/mod)
1-8 GB
Build Cache (GOCACHE)
0.5-3 GB
Installed Go Versions
0.2-2 GB
Installed Binaries (GOBIN)

2. Go Module Cache (go/pkg/mod)

The module cache at ~/go/pkg/mod stores downloaded source code for every dependency version your projects have ever used. This is usually the biggest Go cache.

Audit module cache

# Total module cache size
du -sh $(go env GOMODCACHE)

# Top 20 biggest modules
du -sh $(go env GOMODCACHE)/*/* 2>/dev/null | sort -rh | head -20

# Count unique modules
ls $(go env GOMODCACHE) 2>/dev/null | wc -l

# Find modules with multiple cached versions
ls $(go env GOMODCACHE)/*/ 2>/dev/null | \
  sed 's/@.*//' | sort | uniq -c | sort -rn | head -20

Clean module cache

# Remove entire module cache (safe -- re-downloaded on next build)
go clean -modcache

# Verify it is gone
du -sh $(go env GOMODCACHE) 2>/dev/null
Tip: go clean -modcache is safe. Go will re-download only the modules your current projects need on the next go build or go mod download. Old unused versions will not come back.

3. Go Build Cache (GOCACHE)

The build cache at ~/Library/Caches/go-build (macOS default) stores compiled package objects to speed up rebuilds. It grows without bound.

Audit build cache

# Check build cache location and size
echo "Location: $(go env GOCACHE)"
du -sh $(go env GOCACHE)

# Number of cached objects
find $(go env GOCACHE) -type f 2>/dev/null | wc -l

# Oldest cached files
find $(go env GOCACHE) -type f -printf '%T+ %p\n' 2>/dev/null | sort | head -5

Clean build cache

# Remove all build cache (rebuilds take longer once)
go clean -cache

# Check result
du -sh $(go env GOCACHE)
Performance note: After cleaning build cache, your first go build will be slower (full recompilation). Subsequent builds rebuild the cache quickly.

4. GOPATH Cleanup (Legacy)

If you started using Go before modules (Go 1.11), your GOPATH may contain legacy src/ directory with old vendored code.

# Check GOPATH structure
ls -la $(go env GOPATH)/
du -sh $(go env GOPATH)/src 2>/dev/null
du -sh $(go env GOPATH)/pkg 2>/dev/null
du -sh $(go env GOPATH)/bin 2>/dev/null

# Legacy src/ is safe to remove if all projects use go.mod
# Check first: do any of your projects lack go.mod?
find $(go env GOPATH)/src -name "go.mod" -maxdepth 3 2>/dev/null

# If all projects have go.mod, legacy src/ is unused
rm -rf $(go env GOPATH)/src
Caution: Only remove GOPATH/src if all your projects use Go modules (go.mod). If you have legacy non-module projects, they depend on this directory.

5. Go Toolchains & Versions

Multiple Go versions can accumulate, especially with Homebrew or version managers.

# Current Go version
go version

# Go installed via Homebrew
brew list --versions go 2>/dev/null
du -sh /opt/homebrew/Cellar/go* 2>/dev/null

# Go managed toolchains (Go 1.21+)
ls -la ~/sdk/ 2>/dev/null
du -sh ~/sdk/go* 2>/dev/null

# Extra Go versions installed via go install golang.org/dl/goX.Y
ls ~/sdk/ 2>/dev/null

# Clean old Go SDK downloads
rm -rf ~/sdk/go1.21*  # example: remove old 1.21 toolchains

# Homebrew: remove old versions
brew cleanup go 2>/dev/null

6. Test Cache & Fuzzing Data

The test cache is part of GOCACHE, but fuzzing corpus data is stored separately and can grow significantly.

# Clear test results cache
go clean -testcache

# Find fuzzing corpus data across projects
find ~/Projects -path "*/testdata/fuzz" -type d 2>/dev/null | xargs du -sh

# Clear fuzzing cache
go clean -fuzzcache

# Verify
du -sh $(go env GOCACHE)

7. GOBIN -- Installed Binaries

Tools installed with go install accumulate in GOPATH/bin. Old binaries you no longer use still take up space.

# List installed Go binaries by size
ls -lhS $(go env GOPATH)/bin/ 2>/dev/null

# Total size
du -sh $(go env GOPATH)/bin/

# Find binaries not accessed in 90 days
find $(go env GOPATH)/bin -type f -atime +90 2>/dev/null

# Remove specific unused tools
rm $(go env GOPATH)/bin/unused-tool-name
Tip: Common Go tools like gopls, dlv, staticcheck, and golangci-lint update frequently. After updating, old versions are replaced automatically, but the module cache retains their old source code.

8. Multi-Project Cleanup

If you work on multiple Go projects, each has its own vendor/ directory (if vendoring) and contributes to the shared module cache.

# Find all Go vendor directories
find ~/Projects -name "vendor" -type d -maxdepth 3 2>/dev/null | \
  while read d; do
    if [ -f "$(dirname "$d")/go.mod" ]; then
      echo "$(du -sh "$d" 2>/dev/null)"
    fi
  done | sort -rh | head -20

# Total vendor disk usage
find ~/Projects -name "vendor" -type d -maxdepth 3 2>/dev/null | \
  xargs du -sh 2>/dev/null | awk '{sum+=$1} END {print sum" total"}'

# Remove vendor dirs (go mod vendor regenerates them)
find ~/Projects -name "vendor" -type d -maxdepth 3 -exec rm -rf {} + 2>/dev/null

# Find go binary build outputs
find ~/Projects -name "*.test" -type f 2>/dev/null | xargs du -sh | sort -rh

9. Automated Cleanup Script

Set up a weekly cron job or launchd agent to keep Go caches in check:

#!/bin/bash
# go-cleanup.sh -- Weekly Go cache maintenance for macOS

echo "=== Go Disk Usage Before Cleanup ==="
echo "Module cache: $(du -sh $(go env GOMODCACHE) 2>/dev/null | cut -f1)"
echo "Build cache:  $(du -sh $(go env GOCACHE) 2>/dev/null | cut -f1)"
echo "GOPATH total: $(du -sh $(go env GOPATH) 2>/dev/null | cut -f1)"

# Clean build cache (safe, rebuilt automatically)
go clean -cache

# Clean test cache
go clean -testcache

# Clean fuzzing cache
go clean -fuzzcache

# Optional: clean module cache (uncomment if you want aggressive cleanup)
# go clean -modcache

echo ""
echo "=== Go Disk Usage After Cleanup ==="
echo "Module cache: $(du -sh $(go env GOMODCACHE) 2>/dev/null | cut -f1)"
echo "Build cache:  $(du -sh $(go env GOCACHE) 2>/dev/null | cut -f1)"
echo "GOPATH total: $(du -sh $(go env GOPATH) 2>/dev/null | cut -f1)"

Add to crontab:

# Run every Sunday at 3am
crontab -e
0 3 * * 0 /path/to/go-cleanup.sh >> /tmp/go-cleanup.log 2>&1

10. Prevention & Best Practices

Set GOMODCACHE wisely

# Check current location (default: ~/go/pkg/mod)
go env GOMODCACHE

# Move to a dedicated location if you want easy cleanup
go env -w GOMODCACHE=/path/to/custom/gomod

Use Go workspace mode for multi-module projects

# go.work reduces duplicate module downloads
go work init ./module1 ./module2 ./module3

Keep Homebrew Go tidy

# Remove old Go versions from Homebrew
brew cleanup go
brew autoremove

GOFLAGS for disk-conscious builds

# Disable CGO if not needed (smaller binaries, less cache)
export CGO_ENABLED=0

# Use -trimpath to reduce build cache variability
go build -trimpath ./...

Clean All Developer Caches at Once

Go is just one piece of the puzzle. ClearDisk scans Go caches alongside Docker, Xcode, Homebrew, node_modules, pip, Cargo, and more -- all from your Mac menu bar. Free and open-source.

brew tap bysiber/cleardisk && brew install --cask cleardisk

11. Quick Reference Cheatsheet

Go Cache Cleanup Cheatsheet

# === AUDIT ===
du -sh $(go env GOMODCACHE)    # module cache
du -sh $(go env GOCACHE)       # build cache
du -sh $(go env GOPATH)        # total GOPATH
du -sh $(go env GOPATH)/bin    # installed tools
du -sh ~/sdk/go*               # extra toolchains

# === SAFE CLEANUP ===
go clean -cache                # clear build cache
go clean -testcache            # clear test results
go clean -fuzzcache            # clear fuzz data

# === AGGRESSIVE CLEANUP ===
go clean -modcache             # remove ALL modules
go clean -cache -modcache      # remove everything

# === NUCLEAR ===
go clean -cache -modcache -testcache -fuzzcache

# === ALSO CHECK ===
brew cleanup go                # old Homebrew versions
rm -rf ~/sdk/go1.21*           # old SDK toolchains

Frequently Asked Questions

How much space can I recover from Go caches?

Typically 5-25GB depending on how many projects you work on and how long you have been using Go. The module cache grows with every new dependency version, and the build cache grows with every compilation.

Is it safe to run go clean -modcache?

Yes. The module cache is a download cache. Running go clean -modcache removes it entirely, and Go re-downloads only the modules you actually need on the next build. Unused old versions will not come back.

Will cleaning the build cache break my projects?

No. The build cache only stores compiled object files to speed up rebuilds. After cleaning, your first go build will do a full compilation (slower), but everything works correctly.

What about the go/pkg/mod/cache/download directory?

This is where Go stores downloaded .zip files and .info files for modules. It is included when you run go clean -modcache. You can also check its size separately:

du -sh $(go env GOMODCACHE)/cache/download

How do I prevent the cache from growing so large?

Regular cleanup (monthly go clean -cache) plus judicious use of Go workspaces (go.work) for multi-module projects helps. There is no built-in TTL yet, but it has been discussed in the Go community.