について
このClaudeスキルは、開発者がコンパイルされたGoバイナリとコンテナイメージのサイズを削減するのに役立ちます。リンカーフラグの最適化、依存関係の管理、バイナリ肥大化の原因分析などの手法を提供します。配布用にCLIを縮小する必要がある場合や、バイナリが大きすぎる理由を調査する際にご利用ください。
クイックインストール
Claude Code
推奨npx skills add eduardo-sl/go-agent-skills -a claude-code/plugin add https://github.com/eduardo-sl/go-agent-skillsgit clone https://github.com/eduardo-sl/go-agent-skills.git ~/.claude/skills/go-binary-sizeこのコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします
ドキュメント
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.
- Build a baseline and record its size.
- Find where the bytes are.
- Apply one change class at a time, measuring after each.
- Verify the binary still runs and its tests still pass.
- Report the table of change → bytes saved → cost.
1. Measure First
# 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.
gzip -c /tmp/base | wc -c
2. Strip Symbols and DWARF — the largest single win
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 -wdoes not remove. - ❌
dlvandgdbcan 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/pprofin-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
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
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=1or-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.
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_golangpulls a large surface for a handful of counters.- Anything reflection-heavy: the linker cannot dead-code-eliminate through
reflect, so a reflection-based codec keeps types alive that nothing calls. - Generated protobuf packages for protos you do not use.
Replacing a dependency with 40 lines of standard library is a legitimate size fix. Replacing a well-maintained dependency with your own crypto is not.
7. Embedded Assets
//go:embed content is stored uncompressed.
//go:embed assets/*
var assets embed.FS
Options, in order of preference: ship fewer assets; pre-compress them and
serve with Content-Encoding: gzip; move them out of the binary entirely and
into the container image or a CDN.
8. Container Images
The binary is often the smaller half of the problem.
FROM golang:1.25 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/app ./cmd/app
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /out/app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]
scratch is smaller than distroless/static but ships no CA certificates,
no /etc/passwd, and no timezone database. Use distroless/static unless
you have verified the binary needs none of them.
9. UPX — last resort, usually wrong
upx --best roughly halves the on-disk size and costs decompression on every
start, breaks mmap-based tooling, and is a strong antivirus and EDR
heuristic trigger. Do not pack a binary that ships to end users or runs in a
monitored production environment. Consider it only for a size-constrained
embedded target, and say so explicitly in the report.
Verification
After every change:
go build -o /tmp/candidate ./cmd/app && /tmp/candidate --version
go test ./...
ls -l /tmp/base /tmp/candidate
A smaller binary that no longer starts, or that lost a feature guarded by a build tag, is not a win.
Verification Checklist
- A baseline size was recorded before any flag changed
- Every claimed saving has a before/after number, raw and compressed
-s -wapplied, and an unstripped artifact retained for debugging-gcflags=all=-lbenchmarked, not assumed, on latency-sensitive codeCGO_ENABLED=0measured both ways, not applied blind- Build tags in Makefile, goreleaser, Dockerfile and CI workflows inspected
- Dependency attribution done with a tool, not from intuition
- The candidate binary runs and the test suite passes
- UPX used only with an explicit justification
GitHub リポジトリ
よくある質問
go-binary-size Skillとは何ですか?
go-binary-size はeduardo-sl が作成した Claude Skillです。Skillは、Claudeが必要に応じて読み込む指示とリソースをまとめ、追加の指示なしで go-binary-size に関連するタスクを実行できるようにします。
go-binary-size をインストールするには?
このページのインストールコマンドを使用してください。go-binary-size をプラグインとして Claude Code に追加するか、リポジトリを skills ディレクトリにクローンし、Claudeを再起動してSkillを読み込みます。
go-binary-size はどのカテゴリに属しますか?
go-binary-size は メタ カテゴリに属します。
go-binary-size は無料で利用できますか?
はい。go-binary-size は AIMCP に掲載されており、無料でインストールできます。
関連スキル
このスキルは、Content Collections(Markdown/MDXファイルを型安全なデータコレクションに変換するTypeScriptファーストのツール)の本番環境でテストされた設定を提供します。Zodバリデーションによる型安全性を実現し、ブログ、ドキュメントサイト、コンテンツ重視のVite + Reactアプリケーション構築時にご利用ください。Viteプラグインの設定、MDXコンパイルから、デプロイ最適化、スキーマバリデーションまで、すべてを網羅しています。
このスキルは、開発者がPolymarket予測市場プラットフォームを活用したアプリケーション構築を可能にします。API統合による取引や市場データの取得に加え、WebSocketを介したリアルタイムデータストリーミングにより、ライブ取引や市場活動を監視できます。取引戦略の実装や、ライブ市場更新を処理するツールの作成にご利用ください。
このスキルは、開発者がコマンド、ファイル、LSP操作など25種類以上のイベントタイプにフックするOpenCodeプラグインを作成することを支援します。JavaScript/TypeScriptモジュール向けに、プラグイン構造、イベントAPI仕様、および実装パターンを提供します。カスタムイベント駆動ロジックでOpenCode AIアシスタントのライフサイクルをインターセプト、監視、または拡張する必要がある場合にご利用ください。
SGLangは、高性能なLLMサービングフレームワークであり、RadixAttentionプレフィックスキャッシュを活用したJSON、正規表現、エージェントワークフロー向けの高速で構造化された生成を特長とします。特にプレフィックスが繰り返されるタスクにおいて、大幅に高速な推論を実現し、複雑な構造化出力やマルチターン対話に最適です。制約付きデコードが必要な場合や、広範なプレフィックス共有を伴うアプリケーションを構築する場合は、vLLMなどの代替案ではなくSGLangを選択してください。
