CONCEPT Cited by 1 source
Go build tags¶
Go build tags are file-level compile guards of the form
//go:build <expression> (Go 1.17+; older syntax
// +build <expression>) that tell the Go
compiler whether to include a file in the current build. Build
tags are boolean expressions over OS, architecture, Go version,
CGO state, and user-defined tags.
Semantics¶
A file whose build tag evaluates false for the current build:
- Is excluded from compilation.
- Does not contribute its imports to the package graph.
This second property is the load-bearing one for binary-size engineering. A compile-excluded file's imports (and their transitive imports) never reach the linker — they don't exist in the binary regardless of DCE behaviour.
Two canonical ways to prune a dep¶
Per Datadog (2026-02-18), there are exactly two principal ways to keep an unwanted dependency out of a Go binary:
-
Tag-guard the file that imports it. Mark the file containing the unwanted import with a tag you're not passing (e.g.
//go:build unused). The compiler skips the file; the transitive import tree rooted at it is gone. (patterns/build-tag-dependency-isolation) -
Move the offending symbol to its own package. Binaries that don't need the symbol simply don't import the new package; its dependencies stay out. (patterns/single-function-forced-package-split)
The first is appropriate when a file contains both architecture-specific / optional code and shared code; the second when a single symbol in an otherwise-shared package is dragging in a costly dep stack.
Invocation¶
Built-in tags are implicit (GOOS, GOARCH, go1.24, cgo).
User tags are passed at build time:
Queryable via go list and goda:
GOOS=linux GOARCH=amd64 go list -f '{{ join .Deps "\n" }}' \
-tags kubernetes,otlp,docker ./cmd/agent
Example: plugin unimport¶
The fix for the 2026-02-18 Datadog-containerd regression was
upstream PR
containerd#11203
adding a build tag around the plugin import so downstream
consumers (like the Datadog Agent) that don't need user-loadable
containerd plugins could build without the tag — and therefore
without that import — and see the
concepts/go-plugin-dynamic-linking-implication|245 MiB
regression disappear.
Seen in¶
- sources/2026-02-18-datadog-how-we-reduced-agent-go-binaries-up-to-77-percent
— Datadog Agent's per-feature / per-platform build matrix;
pluginbuild-tag fix upstream.