Context
We evaluated a Datadog-inspired optimization for Go binary size: include only used runtime funcs in generated executables instead of embedding the full internal/runtime/funcs set.
What was prototyped
- Collect used runtime refs from IR (
FuncCall.Ref).
- Parse
runtime/funcs/registry.go and runtime/funcs/*.go.
- Build mapping
ref -> creator -> source file.
- Build transitive file dependency closure via Go AST symbol usage.
- Copy only selected runtime func files and generate minimal
runtime/funcs/registry.go.
Result
- The prototype can significantly reduce small-program binary size/deps (example from PR prototype: ~6.56MB -> ~2.01MB for a minimal case).
- However, implementation complexity became too high for baseline compiler/backend flow and too hard to review/maintain in its current form.
Why we should defer this from baseline PRs
This optimization currently mixes abstraction layers too tightly:
- Neva-level runtime refs from IR,
- Go runtime registry internals,
- Go AST file-level dependency analysis.
This cross-layer coupling increases cognitive load and maintenance risk.
Follow-up design directions (to simplify)
- Move runtime funcs toward clearer package boundaries (currently mostly naming-based grouping).
- Adopt a stronger convention: one runtime func creator per file (or per very small cohesive file set).
- Consider making runtime func refs structured (entity reference), not free-form string only.
- Use package/file-level selection driven by structured refs first; keep AST dependency analysis as optional/secondary.
- Keep build-path improvements (e.g.
-trimpath, -buildvcs=false, shared build args) separate from deep minimization logic.
Measurement and observability
Follow-up work should include repeatable measurements and regression tracking; related meta issue: #1015.
Status
- Keep current PR scope minimal (build flags + small safe refactors).
- Continue runtime minimization as a dedicated design/implementation track.
Context
We evaluated a Datadog-inspired optimization for Go binary size: include only used runtime funcs in generated executables instead of embedding the full
internal/runtime/funcsset.What was prototyped
FuncCall.Ref).runtime/funcs/registry.goandruntime/funcs/*.go.ref -> creator -> source file.runtime/funcs/registry.go.Result
Why we should defer this from baseline PRs
This optimization currently mixes abstraction layers too tightly:
This cross-layer coupling increases cognitive load and maintenance risk.
Follow-up design directions (to simplify)
-trimpath,-buildvcs=false, shared build args) separate from deep minimization logic.Measurement and observability
Follow-up work should include repeatable measurements and regression tracking; related meta issue: #1015.
Status