Why Large Go Projects Build Slowly and How Brad’s -cachelink Can Slash Test Wait Times
Building large Go monorepos often stalls at the linking stage, even when only test parameters change, but Brad Fitzpatrick’s recent -cachelink proposal lets the linker output be cached in GOCACHE, enabling repeated test runs to skip linking and dramatically reduce CI and local testing latency.
When maintaining a large Go monorepo, developers frequently encounter slow builds because the linking step of go test remains costly even after only changing test run flags or executing the same package on different CI nodes. The linker creates a final test binary each time, which can take several seconds for projects with thousands of dependencies.
Ignored Bottleneck: The Cost of Repeated Linking
Go's build cache (GOCACHE) efficiently caches compiled intermediate objects (the .a files), but the final linking of test binaries is performed as a single step. Consequently, even unchanged code triggers a full link when the test command varies, such as using different -run regexes.
# First run: link + execute
$ go test -run=^TestFoo$ ./pkg/
# Second run (no code change): still relinks + execute
$ go test -run=^TestBar$ ./pkg/For large projects, these repeated seconds accumulate into a significant time waste in local debugging and CI pipelines.
Brad’s Solution: The -cachelink Flag
Brad Fitzpatrick submitted proposal #77349, introducing the -cachelink flag. When enabled, the linker’s output binary is written into GOCACHE. The workflow changes as follows:
The toolchain computes a hash based on build inputs (code, dependencies, environment variables, etc.).
If a linked test binary with the same hash already exists in GOCACHE, it is reused.
The linking step is skipped entirely, and the cached binary is executed.
Thus, the second invocation in the example above starts instantly because the expensive linking phase is omitted.
Why Not Enable It by Default?
Brad explains the trade‑off as “space vs. time”. Test binaries contain full symbol tables and debug information, making them much larger than ordinary object files. Caching every test binary would cause GOCACHE to grow rapidly, so the flag is left optional for projects that can afford the extra disk usage or for CI environments where the benefit outweighs the cost.
Distributed CI’s Accelerator
The most compelling use case is in distributed CI systems. Many large companies already share caches across build clusters using GOCACHEPROG. Without -cachelink, each CI node must perform its own linking after pulling the source.
Current state: every machine repeats the linking step, wasting compute resources.
With -cachelink: the first machine that finishes linking uploads the binary to the shared cache; subsequent machines download and run it, reducing the cluster‑wide linking cost to essentially one.
Not Just go test -c
Some developers wonder why not manually compile with go test -c and distribute the binary. Brad points out that manual management bypasses Go’s native test result caching. The -cachelink approach reuses the binary while preserving the full go test experience, including automatic handling of test output and caching.
Conclusion
The proposal is now under active review with an initial implementation available. For teams plagued by slow builds and test cycles, especially those using large Go monorepos, -cachelink promises a practical performance boost that may appear in Go 1.27 or later.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
TonyBai
Tony Bai's tech world (tonybai.com). Not satisfied with just "knowing how", we strive for mastery. Focused on Go language internals, high-quality engineering practices, and cloud‑native architecture, exploring cutting‑edge intersections of Go and AI. Gophers who pursue technology are welcome—follow me and evolve with Go.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
