Skip to content
Agentmart
Submit a tool

go-binary-size

Reduce the size of compiled Go binaries and container images: linker flags, inlining budget, CGO and build tags, embedded assets, dependency weight, and…

Skill by eduardo-sl

IndexedMIT★ 82
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/eduardo-sl-go-binary-size

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Reduce the size of compiled Go binaries and container images: linker flags, inlining budget, CGO and build tags, embedded assets, dependency weight, and measuring what actually costs bytes. Use when a binary or image is too large, when shrinking a CLI for distribution, or when auditing what a dependency adds to the build. Trigger examples: "binary is too big", "shrink the binary", "reduce image size", "strip symbols", "what is making my binary large", "ldflags -s -w". Not for: runtime speed and allocations (go-performance-review), CI setup (go-ci), release pipelines and signing (go-build-release), dependency CVEs (go-dependency-audit).

Use cases: devops, security, productivity, finance

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/go-binary-size

Tools it pre-approves 10

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Read
  • Edit
  • Write
  • Glob
  • Grep
  • Bash(go:*)
  • Bash(gofmt:*)
  • Bash(strip:*)
  • Bash(upx:*)
  • Bash(gsa:*)

What's inside

Skill name
go-binary-size
Description
Reduce the size of compiled Go binaries and container images: linker flags, inlining budget, CGO and build tags, embedded assets, dependency weight, and measuring what actually costs bytes. Use when a binary or image is too large, when shrinking a CLI for distribution, or when auditing what a dependency adds to the build. Trigger examples: "binary is too big", "shrink the binary", "reduce image size", "strip symbols", "what is making my binary large", "ldflags -s -w". Not for: runtime speed and allocations (go-performance-review), CI setup (go-ci), release pipelines and signing (go-build-release), dependency CVEs (go-dependency-audit).
License
MIT
Compatibility
Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain. upx and go-size-analyzer are optional.
Allowed tools
Read, Edit, Write, Glob, Grep, Bash(go:*), Bash(gofmt:*), Bash(strip:*), Bash(upx:*), Bash(gsa:*)
Metadata
author: eduardo-sl · version: 1.0.2
Instructions
196 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves some shell commands

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Go Binary Size

A stock Go binary carries the runtime, the garbage collector, full symbol and
line tables, and every transitively reachable package. 8-15 MiB for a small
CLI is normal. Most of it is removable, but only with measurement — guessing
which dependency is heavy is almost always wrong.

## Procedure

Never apply a flag without a before and after number.

1. Build a baseline and record its size.
2. Find where the bytes are.
3. Apply one change class at a time, measuring after each.
4. Verify the binary still runs and its tests still pass.
5. Report the table of change → bytes saved → cost.

## 1. Measure First

```bash
# Baseline, reproducible
CGO_ENABLED=1 go build -trimpath -o /tmp/base ./cmd/app
ls -l /tmp/base

# Which packages and symbols cost the most
go tool nm -size -sort size /tmp/base | head -40

# Package-level attribution (third-party, more readable)
go install github.com/Zxilly/go-size-analyzer/cmd/gsa@latest
gsa --web /tmp/base
```

`go version -m /tmp/app` prints the module list and build settings baked into
the binary — useful to confirm which flags a release actually used.

Also measure compressed size when the artifact ships in a container layer or
a release archive. Stripping wins less after gzip; removing a dependency wins
more.

```bash
gzip -c /tmp/base | wc -c
```

## 2. Strip Symbols and DWARF — the largest single win

```bash
go build -ldflags="-s -w" -trimpath -o /tmp/stripped ./cmd/app
```

Typically 25-35% off the raw size.

What this costs, precisely:

- ✅ Panic messages and goroutine stack traces still work. The runtime uses
  its own `pclntab`, which `-s -w` does not remove.
- ❌ `dlv` and `gdb` can no longer resolve source lines. Do not ship stripped
  binaries to an environment where you plan to attach a debugger.
- ⚠️ Some profiling and crash-reporting tools that symbolise externally will
  degrade. `net/http/pprof` in-process is unaffected.

Keep an unstripped copy of every release build for post-mortem work.

Add `-buildvcs=false` when the VCS stamp is not needed. It saves little, but
it also removes commit metadata from a distributed artifact.

## 3. Disable Inlining — measure the trade

```bash
go build -ldflags="-s -w" -gcflags=all=-l -o /tmp/noinline ./cmd/app
```

Another 5-10 percentage points. It costs runtime performance on hot paths.
Acceptable for a CLI that starts, does one thing, and exits. Not acceptable
for a latency-sensitive server without benchmarking the regression first.

## 4. CGO and the Runtime

```bash
CGO_ENABLED=0 go build -tags netgo,osusergo -ldflags="-s -w" -o /tmp/pure ./cmd/app
```

These three go together: disabling cgo without `netgo,osusergo` leaves the
build depending on the C resolver stubs.

Check before assuming it helps:

- `go list -deps ./... | xargs go list -f '{{.ImportPath}} {{.CgoFiles}}'`
  shows which packages actually use cgo.
- Disabling cgo can **increase** size when the pure-Go replacement of a C
  binding is larger. Measure both.
- If the release config already sets `CGO_ENABLED=1` or
  `-linkmode=external`, there is a reason. Find it before changing it.

When cgo must stay and the project compiles C sources (SQLite bindings, image
codecs), `CGO_CFLAGS="-Oz"` optimises that C code for size.

## 5. Build Tags — the step most often skipped

Heavyweight optional features are usually gated behind tags that live outside
the Go source.

```bash
grep -rn '//go:build' --include='*.go' . | grep -v _test.go
grep -rnE '\-tags' Makefile Taskfile.y*ml .goreleaser.y*ml Dockerfile .github/workflows/ 2>/dev/null
```

Common wins: dropping a driver you do not use, excluding an admin UI from the
production build, building a `noembed` variant that fetches assets at runtime.

## 6. Dependency Weight

A single import can dominate the binary. `gsa` attributes bytes per module —
start there, not from intuition.

Recurring offenders:

- Cloud provider SDKs. Import the individual service package, never the
  aggregate root.
- `github.com/prometheus/client_golang` pulls a large surface for a handful

From eduardo-sl/go-agent-skills, MIT.

More from eduardo-sl/go-agent-skills

Signals

Stars
82
Forks
10
Open issues
0
Last commit (this folder)
Oct 15, 2026 (14 days ago)

From GitHub (fetched Oct 24, 2026).

Details

Version
1.0.2
License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from eduardo-sl

Cite this page

go-binary-size skill. Agent Mart. https://agentmart.dev/skills/eduardo-sl-go-binary-size (last updated 2026-10-24)