> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blacksmith.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Go Build Caching

> Blacksmith caches your Go builds and test results across runs

export const ProductEmbed = ({story, title, width, height}) => {
  const productionOrigin = "https://docs-embeds.blacksmith.sh";
  const knownOrigin = () => {
    if (typeof window === "undefined") return undefined;
    if (!(/^localhost$|\.mintlify\.(app|site)$/).test(window.location.hostname)) return productionOrigin;
    return window.__blacksmithEmbedOrigin;
  };
  const designWidth = width || 960;
  const designHeight = height || 600;
  const frameRef = useRef(null);
  const [embedOrigin, setEmbedOrigin] = useState(knownOrigin);
  const [ready, setReady] = useState(false);
  const [live, setLive] = useState(false);
  const [requested, setRequested] = useState(false);
  useEffect(() => {
    const frame = frameRef.current;
    const box = frame && frame.parentElement;
    if (requested || !box) return undefined;
    const request = () => setRequested(true);
    const observer = new IntersectionObserver(entries => {
      if (entries.some(entry => entry.isIntersecting)) request();
    }, {
      rootMargin: "100px 0px"
    });
    observer.observe(box);
    frame.addEventListener("blacksmith-embed-load", request);
    return () => {
      observer.disconnect();
      frame.removeEventListener("blacksmith-embed-load", request);
    };
  }, [embedOrigin, requested]);
  useEffect(() => {
    if (embedOrigin) return undefined;
    const resolve = () => setEmbedOrigin(knownOrigin() || productionOrigin);
    if (knownOrigin()) return resolve();
    window.addEventListener("blacksmith-embed-origin", resolve);
    const timer = setTimeout(resolve, 5000);
    return () => {
      window.removeEventListener("blacksmith-embed-origin", resolve);
      clearTimeout(timer);
    };
  }, [embedOrigin]);
  useEffect(() => {
    const frame = frameRef.current;
    const box = frame && frame.parentElement;
    if (!box) return undefined;
    const fit = () => {
      frame.style.transform = `scale(${box.clientWidth / designWidth})`;
    };
    fit();
    const observer = new ResizeObserver(fit);
    observer.observe(box);
    return () => observer.disconnect();
  }, [designWidth, embedOrigin]);
  useEffect(() => {
    const onMessage = event => {
      if (event.origin !== embedOrigin) return;
      if (!frameRef.current || event.source !== frameRef.current.contentWindow) return;
      if (event.data && event.data.source === "blacksmith-docs-embed" && event.data.type === "ready") {
        setReady(true);
        if (!event.data.snapshot) setLive(true);
      }
    };
    window.addEventListener("message", onMessage);
    return () => window.removeEventListener("message", onMessage);
  }, [embedOrigin]);
  if (!embedOrigin) return null;
  return <iframe ref={frameRef} className={ready ? "is-ready" : undefined} data-embed-live={live ? "" : undefined} src={requested ? `${embedOrigin}/embeds/${story}` : undefined} data-embed-story={story} width={designWidth} height={designHeight} title={title} onLoad={event => {
    if (event.currentTarget.getAttribute("src")) event.currentTarget.setAttribute("data-loaded", "");
  }} tabIndex={-1} />;
};

## Overview

Go's build cache keeps local development fast, but CI starts every job with an empty cache and compiles everything from scratch. Blacksmith connects Go's native cache protocol ([`GOCACHEPROG`](https://pkg.go.dev/cmd/go/internal/cacheprog)) to a cache shared across runs, workflows, and machines, so `go build`, `go test`, and `go vet` reuse prior work automatically. There are no cache actions to add, no cache keys to manage, and no `GOFLAGS` changes to make.

Go build caching requires Go 1.24 or newer. Older toolchains do not support this integration, so keep your existing build cache for jobs that use them.

## How it works

Go hashes every package build against its inputs: source files, dependencies, build tags, compiler flags, and the toolchain version. Blacksmith stores each result under that hash. When a later run builds a package whose hash matches, Go links the cached object instead of compiling. The same applies to `go vet` facts, and optionally to passing test results. A change invalidates only the packages it reaches through the import graph, so a one-line edit recompiles a handful of packages while the rest of the build reads from cache.

Each repository has its own cache, shared across branches and pull requests, so merging to `main` warms the cache for every branch that follows. Caches are separated by CPU architecture and never shared across repositories or organizations.

## Enable Go build caching

Go build caching is enabled by default for new organizations. An organization admin can turn it on or off from [**Settings > Caching**](https://app.blacksmith.sh/settings/caching) in the Blacksmith dashboard, under **Build systems**.

<div className="product-embed not-prose">
  <div className="product-embed-window">
    <div className="product-embed-screen" style={{ backgroundImage: "url(data:image/webp;base64,UklGRpwHAABXRUJQVlA4IJAHAAAwMwCdASpAAcgAPtForVEoJiQio1J5+QAaCWlu7o1CTnLqf5Ne67qlFxw+E722aQIGDlwEZBKGZE28j969QPpgjEH57x2JQAyK/lrqcLF9HMycqqqqqqqqqpUZR7dC1yJ3p9QWGd3d3d3d3dzvGTqgz7Z1s+4yUA4/fZOhxc21sYxjGMYxispU/jRT/DasuYxrIQot8ZZ3CAe6HVOOfmyIIF1PS5Vi2x9IK5iTMCKqcrV3d0wWitGPcEGxtY8LXqUHHAyOqKs2sVqEIQgL7kCqzKRIEXPLi73RdQzjGMYxjGMOFWFU2skowX9teu5aHDLC0II/Lz8HgwUs27vmxqTtUZgQujP/++7iGkzKFDEDgJ1gUPFwgFMbu6kU545/////GfdFjxxL3nfWb4QDE1waRikG0jo521qIH//9FYAroluLOM6A5ZREe5i0RczC+4cj1wznI1X7YU/9zes4xjGMMi9zkZ473Ugg0srU2/FliA+hWXxf2DGq9CEpRVi1Hn2AGv69rCj+d7cjond3bXBKfMqg3EOxDZtBpyEIpCEIQdkAAP78EYsVntxSN5bq+M69rLczdtIpiRIFYnRg6ibIZTgv7RUuAqCWCMxbEtz8qGRvci1Vh/9ZdLfFTv8Q6DCQeO7s3vvqx3VICdjWdRsT8eifOZGKbxcxeBEjUSp4cmUgRsu0PLFiEkIkJuk+/DQ07ljvRq0Ra4oZ3OtDratJ9wpiq0lKpmoQW2DWY+513dydnM1XhYArPk3bUOS31BxHeXhxoP4Nq4QJbeQpiP+KQ5Be5cVduOqVp62CFlpV29qO5BmrXGsZR2fo6WzzMKkhYIG/evnB+R8O1i0xOrNN58s5j2sf8JHNQh0fI4XSd+ci2knkh6k4iI6O1Sn9vDo3X6JH8du28DhJCpigUxltJk4gPJom2ePdCIFFXnB6uPNjCuiP0aeQxsuj7bGMy0eQjZ3zMQS1tbWiCQmCasVYjaSPsnB9ZxRVVv7hHooTl86DzwtXBb6TE7aWKAKQjrojtoc7lwnLTazxhgPz0nwJunfuMZLnyogKxVujgl850CO0gPqV0FYY8mMo/MQcdLowxaz54mth31L/1lCkkqT7r7HgEvd1kUzUpDUA1eAH3NCF+SfDEO1wEXjH00pcxcrWntpWHxRZ99mD4BH41PCfGwVLGSvE+N4oqLkBlfY14LZ8r7lfSKwP9vu+O4DrmjWE9s3SEoL5k7rW09VUP3W3coGYYNfNTnbP2BgNTeCU7Matbbtx/G3TR3vkbVbohBGXHrFzEfjJpnTmNx2k79OudjCtZqZITVSGfB8Pxxia0prxi9Fig/1z7ebDBzmsiiGLv1cDDpy9RxjYdTrArNcAvPusmbMx4o7fGjVfAzDQUHEiWPyT4B+hYC7zyqEHTDt7dq6VpkWL5NFTnPL4dlnjowpYDizqWGIL/9z3gdq3nkdfKOPmN6huPx8MOSFx4MXX/Py63FP29lVliUwdHZ8CcCuIsuZShKN0S6X7pq+jIRMWYQy2IvZgtjNAy7x2B/upz/LXogdzSsLemHS9Wq9FggyjUhugoct2X4zlCpTo/DXnkWF4J8zrP9Xc7E/2ZRWYUndnP9mpMX7Ytbhlx6/LX7+8KgTJMfZbrTcz6i9ua46voeRm6Si1aTQb8IzZfww/503jGeXVADhWj9OjqYl0/4Kkc80EeFhAC3AQODERF8oJvP3qpla43KV0+LFWcuV2Gfr1kFwtVO2PusQUEGadPkVpHdOtLsMXSywy6labkP5tpo3TzDFD3jljqzmrv7vHTI7REMWiP4qiRFYYbnqV+wuB7sZPLnXZ/yzcMMtpPnZ2kWkoBtP2MIOmeTG7CA1sZupNReARkHJWDzMj6ipsVYBg0+rINrE9/U3uT77ELvEk+ePfurrO1j/99b127zAIa0fP3SXbMmGiRVuW3PNnInvWAr4ivHOu3MJimLe+7JISbzY/P/hXKdLC8Y4KMoYEQwaFmkMSzmozQZo11hSD29+c4Su/nUQjp2+6LVpwIVCypD3ovAHBzPCGqi3T80sXhKRWzlCfSe8hAADAllnL6EVbhCNeqeote7yriihrcFrP8YBqplCWIPtq/HJodaT7qQ5gfFkiaUC4yagS27D84GJzdzCcVEo4e70a2aV4eQqrYFWrBFtUfuVxCbTbDgVeUfB4qC5HFyM+9eENzPNndV8tuHqGvH6Y/u67t0XoKc4HNc66KqeuzFFDaBnLmz3828V6gsLhwzwatNejlTbvJKYN8G+w+RZwkET4Sxdl2/yzuE7VP3GYjUu0kdI6YUVbVHNEfqFYnC4bCtH2yQFIMogsl9kLHtbNYbL3jrQ7C7o2ZX2yaUpowneYpsDfvuL6MPWrGyokYhDx/r425Ah9QhU5aDk1cxQJO+Dd/q2qQaQl3YfKvfmLiQcXbcPVPltBPZTsZEwlAegH/pxKefZSVeNoOgABrSyg7fR4tNWEfBGhpZCidH1UoMwm/IxECFjAlbYg49lOfsW+qhv0yySsDKcJ0wwM9uI67oIWG9KKY8V8/b9aQxD5MaNDewg/oMjULFtRq9CbVpJzZABiRAAA)" }}>
      <img className="product-embed-poster" src="https://mintcdn.com/blacksmith/Itk-j1vuc5ra3oOQ/images/embeds/settings-caching.png?fit=max&auto=format&n=Itk-j1vuc5ra3oOQ&q=85&s=4645b49861ca4cd88d322dc9fac35dd6" alt="An admin turning on Go build cache in Settings > Caching" noZoom data-og-width="1920" width="1920" data-og-height="1200" height="1200" data-path="images/embeds/settings-caching.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/blacksmith/Itk-j1vuc5ra3oOQ/images/embeds/settings-caching.png?w=280&fit=max&auto=format&n=Itk-j1vuc5ra3oOQ&q=85&s=023e420024c17b401e1249f34fe2f108 280w, https://mintcdn.com/blacksmith/Itk-j1vuc5ra3oOQ/images/embeds/settings-caching.png?w=560&fit=max&auto=format&n=Itk-j1vuc5ra3oOQ&q=85&s=67eeae8fddf37fd66500552c8f78eb01 560w, https://mintcdn.com/blacksmith/Itk-j1vuc5ra3oOQ/images/embeds/settings-caching.png?w=840&fit=max&auto=format&n=Itk-j1vuc5ra3oOQ&q=85&s=a1b3e2573265ddac89604a841946701e 840w, https://mintcdn.com/blacksmith/Itk-j1vuc5ra3oOQ/images/embeds/settings-caching.png?w=1100&fit=max&auto=format&n=Itk-j1vuc5ra3oOQ&q=85&s=0f70e5c84199d22657b05baf69f05587 1100w, https://mintcdn.com/blacksmith/Itk-j1vuc5ra3oOQ/images/embeds/settings-caching.png?w=1650&fit=max&auto=format&n=Itk-j1vuc5ra3oOQ&q=85&s=8fe722df8749acbbe2df584301750eb5 1650w, https://mintcdn.com/blacksmith/Itk-j1vuc5ra3oOQ/images/embeds/settings-caching.png?w=2500&fit=max&auto=format&n=Itk-j1vuc5ra3oOQ&q=85&s=39cabc4047d277ea4d5ce30d4dc6ad88 2500w" />

      <ProductEmbed story="docs-embeds-settings--go-build-cache" title="An admin turning on Go build cache in Settings > Caching" />
    </div>
  </div>
</div>

### Replacing actions/cache

Go build caching completely replaces the Actions cache for your Go jobs. If your workflows cache Go builds or tests with `actions/cache` or `actions/setup-go` today, remove that caching and enable Go build caching instead. Your jobs skip the cache download and upload entirely and get faster builds.

## Test result caching

**Go test cache** is an organization-wide option under **Go build cache**. When it is on, a test that passed in one run replays as `(cached)` in later runs with unchanged inputs, so retries and merge queue runs skip tests they already passed.

It is off by default because caching is only safe for hermetic tests. Go tracks the environment variables and files a test reads and re-runs it when any of them change, but it cannot see external state like databases, network services, or the clock. If your suites depend on that kind of state, leave this off, or opt out for a single job:

```yaml theme={"system"}
env:
  BLACKSMITH_GOCACHEPROG_DISABLE_TEST_SHARING: "1"
```

Tests run with `-count=1` are never cached, matching stock `go test`.

## Verify cache hits

Go doesn't announce build cache hits in its output; the visible signals are faster `go build` steps and `(cached)` markers in test output. For the full picture, open the [Cache page](https://app.blacksmith.sh/cache), choose a repository, and open the **Go** tab. Hit rate there counts what your builds actually experienced, whether a hit was served from the runner's local store or the shared cache. The first builds populate the cache, so compare hit rate and step durations across later runs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.