CONCEPT Cited by 1 source
Transitive-dependency reachability¶
Transitive-dependency reachability is the graph-theoretic reason a package's cost depends on how it's imported: importing a package transitively brings in every package it imports (that isn't excluded by build constraints), plus the runtime.
Formal shape¶
- Nodes: Go (or language-X) packages.
- Edges: direct imports, filtered by build tags /
GOOS/GOARCH/ preprocessor conditions. - Reachable set from package
M: the transitive closure of outgoing edges fromM. - Binary includes: every package in the reachable set from
main, plus the linker's view of which symbols in each package are reachable (subject to DCE).
Why it matters operationally¶
A single directly-imported package with one edge to a heavy dep can drag the whole heavy dep into the binary. Worse, the edge can be hidden inside a shared utility package that multiple binaries use for unrelated reasons.
Canonical wiki instance (Datadog 2026-02-18)¶
Datadog Agent trace-agent binary:
go listshowed 526k8s.io/*packages included.- systems/go-size-analyzer attributed ≥30 MiB to them.
- systems/goda's
reachfunction traced the entire k8s import graph back to one function in one package of the Agent codebase. The function itself had no Kubernetes dependency; the package it lived in did.
Fix: move the function into its own package (patterns/single-function-forced-package-split). Binaries that only needed the one function stopped importing the original package and its heavy dep cluster.
Result: 570 packages removed, 36 MiB binary-size cut — "more than half of the binary".
Tools to reason about it¶
go list -f '{{ .Deps }}'— what's included.- systems/goda
reach(main, target)— the import paths frommainto any target package. - systems/go-size-analyzer — byte cost per package (where DCE interacts with reachability).
Design implications¶
- Shared utility packages are amplifiers. A single heavy import in a package used widely turns a localized cost into a global one.
- Audit edges not packages. The binary-size engineering question isn't "is this package expensive?" but "is there an edge whose removal would drop a big subgraph?"
- One-edge fixes are common. The 2026-02-18 post explicitly frames the k8s case as "an extreme example, but not a unique one. We found many similar cases."
Generalises beyond Go¶
C/C++ include graphs, Python import side effects, npm package.json
direct + transitive deps, JVM classpath reachability — same graph
model, different language-specific edges + pruning mechanisms.
Seen in¶
- sources/2026-02-18-datadog-how-we-reduced-agent-go-binaries-up-to-77-percent — k8s single-function / 570-package / 36-MiB canonical instance.