Skip to content

perf(build): cut CLI startup time - #2181

Merged
tejaskash merged 2 commits into
refactorfrom
perf/startup
Sep 3, 2026
Merged

perf(build): cut CLI startup time #2181
tejaskash merged 2 commits into
refactorfrom
perf/startup

Conversation

@tejaskash

@tejaskash tejaskash commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Profiling agentcore --version showed ~10 ms of actual work inside ~620 ms of wall time. This PR removes the three largest self-inflicted costs in the build.

  1. Dedupe @smithy/core. package.json pinned it at 3.29.3 while every @aws-sdk/client-* wanted ^3.33.3, so bun nested 51 private copies and the bundler inlined all of them (34 copies of httpAuthSchemeMiddleware in the bundle). Bumped to ^3.33.3. Bundle: 9.2 MB → 5.6 MB.
  2. Production React. NODE_ENV was never defined at bundle time, so both the npm bundle and the compiled binary carried React's development build (runWithFiberInDEV etc.). Both builds now define it as production.
  3. V8 compile cache. dist/index.js is now a four-line loader that calls module.enableCompileCache() and imports the bundle at dist/main.js. V8 only caches modules loaded after the call, so a single-file bundle cannot cache its own compilation. No-op on Node < 22.1. Bun inlines relative imports even when marked external, so the build script writes the loader directly.

bin, main, node dist/index.js, and the Makefile/README references are unchanged: dist/index.js is still the entry, it just delegates.

Measurements

Artifact size:

Artifact Before After
npm bundle (dist/main.js) 9.24 MB 5.58 MB (−40%)
darwin-arm64 binary 85.1 MB 76.0 MB (−11%)

agentcore --version, median of 7 runs, telemetry enabled:

Runtime Before After
Node 20.20 620 ms 475 ms
Node 24.15 478 ms 407 ms
darwin-arm64 binary 652 ms 442 ms

With AGENTCORE_TELEMETRY_DISABLED=1 (isolates startup from the exit flush): Node 24 311 ms → 246 ms, binary → 300 ms.

Not in this PR

  • Telemetry exit flush (140–180 ms, network-bound HTTPS POST in OtelHistogramSink.shutdown) is now the largest remaining cost. Needs a design decision (spool-and-forward vs. detached flusher); follow-up.
  • Bun bytecode for the binary is not possible: it requires CJS output, and ink and yoga-layout use top-level await.

Verification

  • bun test: 2803 pass, 0 fail
  • bun run typecheck, bun run lint:check, prettier --check: clean
  • bun run build and bun run compile:darwin-arm64: both artifacts run --version and render the interactive TUI (root menu, harness submenu) with the production React build
  • Compile cache confirmed populated under os.tmpdir()/node-compile-cache on Node 24

…ion React, and enabling the V8 compile cache

@smithy/core was pinned at 3.29.3 while every @aws-sdk client wanted
^3.33.3, so bun nested 51 private copies and the bundler inlined all of
them. Bumping the pin shrinks the bundle from 9.2 MB to 5.6 MB.

The bundle carried React's development build because NODE_ENV was never
defined at bundle time. Both builds now define it as production.

dist/index.js is now a four-line loader that calls enableCompileCache()
before importing the bundle (dist/main.js). V8 only caches modules loaded
after the call, so a single-file bundle cannot cache itself. The loader is
a no-op below Node 22.1.

`agentcore --version`, median of 7 runs:
  Node 20:  620 ms -> 475 ms
  Node 24:  478 ms -> 407 ms
  binary:   652 ms -> 442 ms

The remaining 140-180 ms is the telemetry HTTPS flush at exit, left for a
follow-up.
@github-actions github-actions Bot added the size/m PR size: M label Sep 3, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Sep 3, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 3, 2026

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Nice, tight change. Three things bundled together, all reasonable:

  1. NODE_ENV=production define (scripts/build.ts) — necessary for React/Ink to select their production build. Verified nothing under src/ reads process.env.NODE_ENV, so this token replacement has no unintended side effects on our own code. Applied to both bundle and compile, which is correct.

  2. V8 compile-cache loader (scripts/build.ts + src/index.ts) — the split into dist/index.js (loader with shebang) → dist/main.js (bundle) is the right shape: enableCompileCache() must run before the modules you want cached, and the dynamic await import("./main.js") runs after. Sanity-checked:

    • resolveAssetsRoot() in src/core/project/source.ts uses import.meta.url from the bundle, so dist/main.js/../assets still resolves correctly.
    • No downstream references to dist/index.js other than the bin/main fields in package.json, which still point at a valid ESM entry.
    • type: module + ESM loader + ESM bundle line up.
  3. @smithy/core bump 3.29.3^3.33.3 — only ServiceException and WaiterState are imported from @smithy/core/client, both stable. Deduping the huge block of nested overrides in bun.lock is a nice side effect.

No test or telemetry changes needed for a build-time perf tweak. LGTM.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 3, 2026
@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.08%. Comparing base (16db5b4) to head (0cd8499).

Additional details and impacted files
@@            Coverage Diff            @@
##           refactor    #2181   +/-   ##
=========================================
  Coverage     97.08%   97.08%           
=========================================
  Files           536      536           
  Lines         36979    36979           
=========================================
  Hits          35901    35901           
  Misses         1078     1078           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tejaskash tejaskash changed the title perf(build): cut CLI startup time (smithy dedupe, production React, V8 compile cache) perf(build): cut CLI startup time Sep 3, 2026
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 3, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 3, 2026
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026

@AlexanderRichey AlexanderRichey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice finds!

@tejaskash
tejaskash merged commit 5b22780 into refactor Sep 3, 2026
33 of 36 checks passed
@tejaskash
tejaskash deleted the perf/startup branch September 3, 2026 18:27
This was referenced Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants