Skip to content

perf(claude-code): cut 500 MB of waste and share layers across targets - #196

Merged
gatezh merged 2 commits into
masterfrom
perf/claude-code-image-size
Oct 6, 2026
Merged

gatezh merged 2 commits into
masterfrom
perf/claude-code-image-size

Conversation

@gatezh

@gatezh gatezh commented Oct 6, 2026

Copy link
Copy Markdown
Owner

What

Trims ~500 MB of dead weight from the claude-code images and makes the default and sandbox targets share their heavy layers. No tools are added or removed.

Why

The image had grown to 2.82 GB on disk and an 812 MB download. About 280 MB of that was waste: download caches and binaries for other platforms. The Claude Code layer, which Renovate bumps almost daily, was 214 MB compressed, half of it the npm cache, so every bump cost consumers that much. Default and sandbox shared no heavy layers, so anyone using both downloaded Chromium and Claude Code twice.

Changes

  • npm cache out of the image: npm install -g uses --cache /tmp/npm-cache on a BuildKit cache mount, so ~/.npm/_cacache (~160 MB across the two installs) is no longer shipped.
  • agent-browser trimmed: after install, the six non-matching platform binaries (darwin, win32, musl…) are deleted. The global agent-browser link targets bin/agent-browser-linux-<arch> directly. 174 → 19 MB.
  • gh cache dropped: rm -rf ~/.cache/gh after gh extension install. That cache is gh's HTTP cache holding a 25 MB copy of the gh-stack download.
  • New shared stage: sudoers, Chromium and Claude Code move into a shared stage that both targets build FROM. default adds agent-browser and AGENT_BROWSER_EXECUTABLE_PATH; sandbox adds only the firewall packages. The two images now share 22 of 23 layers.
  • Roadmap: adds docs/plans/2026-10-06-claude-code-image-size-roadmap.md. It holds the baseline measurements, this tier's results, and the next steps: stripping Chromium's unused LLVM/Mesa libraries, and splitting the browser out of the core image.

Results (local amd64 build)

Before After
On disk 2.82 GB 2.32 GB
Download (Docker content size) 852 MB 633 MB (−26%)
Claude Code layer per bump (compressed) 214 MB 108 MB
Sandbox on top of default separate stack +17.6 MB

Notes

  • Trade-off: Claude Code now sits below the target-specific layers, so each Claude Code bump also rebuilds the small agent-browser (19 MB) and firewall (18 MB) layers. The large Chromium layer is still unaffected by bumps.
  • Verified locally: hadolint passes with the repo config, and CI's verify commands pass for both targets. Headless Chromium renders a page. agent-browser opens and snapshots a page. Runtime npx works and creates a node-owned ~/.npm. No ~/.npm, /tmp/npm-cache or ~/.cache/gh is left in either image.
  • Only amd64 was built locally. arm64 gets its first build on the multi-arch build after merge.
  • Target names and build commands are unchanged, so consumers need no changes.

gatezh added 2 commits October 6, 2026 13:26
- npm installs use a BuildKit cache mount (--cache /tmp/npm-cache), so the
  ~160 MB npm cache no longer ships in the image.
- Delete agent-browser's six non-matching platform binaries (~95 MB); the
  global link targets agent-browser-linux-<arch> directly.
- Drop gh's 25 MB HTTP cache left by the gh-stack install.
- New `shared` stage (sudoers, Chromium, Claude Code) that both targets build
  FROM, so default and sandbox share 22 of 23 layers.

Local amd64: 2.82 -> 2.32 GB on disk, 852 -> 633 MB download; the Claude Code
layer re-pulled on each bump drops from 214 to 108 MB compressed.
@gatezh
gatezh merged commit adeef37 into master Oct 6, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant