Explain the build cache, the module cache and test result caching. When does go test print "(cached)" and how do you defeat it?
There are two separate caches:
- Module cache (
GOMODCACHE, default$GOPATH/pkg/mod): extracted, read-only module source plus the downloaded zips and go.mod files incache/download. Clear it withgo clean -modcache.-modcacherwleaves the files writable. - Build cache (
GOCACHE,go env GOCACHE): content-addressed outputs keyed by an action ID, which is a hash of every input (source files, imported package outputs, compiler flags, relevant env such as GOOS/GOARCH/CGO_* and the toolchain version). It is safe to share between branches. Clear it withgo clean -cache. Since Go 1.24,GOCACHEPROGlets an external program provide the cache (for example a remote CI cache).
Test caching happens only in package list mode (go test ./... or go test ./pkg). Plain go test with no package arguments (local directory mode) never caches. A result is reused when the test binary, the cacheable flags (-run, -short, -v, -timeout, -cpu, -list, -parallel, -benchtime, -failfast, -count...) and the environment variables and files the test read (tracked through os.Getenv and os.Open) are all unchanged.
go test ./... # ok example.com/store (cached)
go test -count=1 ./... # idiomatic way to force a re-run
go clean -testcache # drop all cached test results
GODEBUG=gocachehash=1 go build ./... # debug why something rebuilds
Gotchas: the cache does not know about network services, databases or files outside what the test opens, so integration tests can report stale "(cached)" passes. Use -count=1 for them. Any flag outside the cacheable set (for example a custom flag passed with -args) disables caching for that run. Only successful results are cached.
More on Modules, Packages & Tooling
- Q439How does Go ship behavior changes without breaking old code? Explain GODEBUG, the godebug directive and //go:debug. What does this print?
- Q440What are module graph pruning and lazy module loading (Go 1.17), and why did go.mod files get so much longer?
- Q442What is //go:linkname, and what changed about it in Go 1.23?