deniz.in

Markets

Weather

Loading weather

· via Hacker News – Front Page (native)

CloudX open-sources setup-go replacement that cuts Go CI test runtimes by 69%

CloudX open-sourced a drop-in replacement for GitHub's actions/setup-go that keeps Go's build and test caches effective across parallel CI jobs, cutting test runtimes by 69%.

CloudX open-sources setup-go replacement that cuts Go CI test runtimes by 69%

What happened

CloudX, a company that runs a web monorepo with parallel Go lint, test and build jobs, has open-sourced a GitHub Action called cloudx-io/setup-go. According to a CloudX blog post that reached the front page of Hacker News, the action is a drop-in replacement for GitHub's official actions/setup-go, and swapping it in cut the company's Go test job runtimes by 69%.

Backtesting against their repository, CloudX estimates that about 86% of the work performed under the default action's caching setup was unnecessary. The company frames the change as part of a broader engineering effort: it aims to give engineers a definitive build-and-test verdict within 90 seconds of a push, and already runs its CI on Warp Build machines.

Where actions/setup-go's caching goes wrong

The official action persists Go's module and build caches between runs using actions/cache. The weakness CloudX identifies is the cache key, which is derived from inputs such as the operating system, CPU architecture, Go version and go.mod contents. In an actively developed codebase, almost no change touches any of those.

The first job to run computes that key and saves its final cache state to GitHub's cache service. Because the key rarely changes, every subsequent run restores that same original snapshot. As the codebase moves on, the restored build archives and test results correspond to older code, so each build redoes more work from scratch and each run re-executes more tests. CloudX says performance degrades until a go.mod change finally rotates the key.

Parallel jobs make it worse. Separate lint and test jobs resolve the same default key and then race to write it. GitHub's cache entries are immutable once written, so only the first writer wins: if the lint job finishes first, the saved value lacks updated test results, and later test jobs keep restoring that stale value and re-running tests.

Go already solves this, if the cache survives

CloudX's argument is that the Go toolchain itself is an excellent memoizer. The module cache (GOMODCACHE) stores downloaded dependency sources, while the build and test caches share the GOCACHE directory, which sits at ~/.cache/go-build on Linux. Build and test processes hash their full inputs and store reusable outputs: package archives for builds, and captured stdout, stderr and exit codes for tests. The test runner even monitors which files a test reads and folds their contents into the hash, so results are reused only when their inputs are genuinely unchanged.

That design works on a persistent filesystem. Ephemeral CI runners have none, so these toolchain caches must be shuttled between runs through GitHub's cache service, a simpler key-and-path store that only saves on job success, only on a primary-key miss, and never overwrites an existing entry. The mismatch between the two caching layers is where hit rates collapse.

What the replacement changes

CloudX's action keeps the same usage as the official one but rethinks the caching strategy so that Go's native caches stay effective across parallel jobs. The company says it deliberately accepts duplicated setup work and higher cache storage costs: parallelizable work should run in parallel even if that increases billed runner time, and a few extra dollars a month for cache space is cheaper than blocked engineers and coding agents. The core insight, per CloudX, is that the Go toolchain's caching is already very good, and the CI layer's job is not to undermine it.

Why it matters

For any team running multiple Go jobs in GitHub Actions, this is a low-cost experiment: replace one action reference and measure. CloudX claims similar gains should be reachable for moderately complex Go projects, though the headline numbers come from one company's monorepo, and workloads with very fast tests or trivial builds will see less benefit.

More broadly, the post is a useful case study in cache key design on ephemeral CI infrastructure. GitHub's cache immutability and save-once semantics are reasonable in isolation, but combined with coarse keys they can quietly neutralize the sophisticated caching a toolchain like Go provides. Faster CI compounds: shorter feedback loops keep both engineers and coding agents unblocked, which is exactly the outcome CloudX says it is paying for.

  • #go
  • #github-actions
  • #continuous-integration
  • #open-source
  • #caching

Related posts