Skip to content

Defer worker startup imports in apps/cloud - #2068

Draft
RhysSullivan wants to merge 1 commit into
mainfrom
lazy-worker-entry
Draft

RhysSullivan wants to merge 1 commit into
mainfrom
lazy-worker-entry

Conversation

@RhysSullivan

Copy link
Copy Markdown
Collaborator

Four static edges out of the Worker entry are now dynamic imports, memoized per isolate, so a cold isolate evaluates only the code the path it is about to serve needs:

  • @tanstack/react-start/server-entry — loaded inside fetchHandler. An isolate serving only /api or /mcp never evaluates react-dom or the router. markStartGraphEntered() still runs synchronously on entry, so the flag means the same thing.
  • makeCloudMcpAgentHandler — built on the first /mcp request.
  • ExecutionRateLimiterDO — Cloudflare requires a DO class as a top-level export, so the export is now a thin DurableObject shim that imports the real two-method counter and delegates increment and alarm to an instance built from the same ctx/env, memoized per DO instance.
  • runWorkOsEventsSync — imported inside scheduled.

McpSessionDOSqlite is deliberately left static. The same shim pattern would have to forward partyserver's setName plus roughly fifteen @internal RPC methods the agents SDK calls straight on the stub, and streamable-http bridges through a hibernatable WebSocket into the DO. A missed or newly added method fails at the call site in production, and stub calls are dynamic so nothing catches it at build time. It is worth 1.05 MB, measured; the reasoning is in a comment at the export.

Also on worker.dispatch: executor.dispatch.graph_import_ms, measured around getAppPlane(). workerd freezes Date.now() until the first real I/O, so a cold app-plane dispatch performs one throwaway caches.default.match first — otherwise the measurement reads 0 and the cold graph cost lands on whatever span straddles the next I/O (the Sep 2026 investigation mis-attributed it to workos.session.local_verify). Warm dispatches skip it.

scripts/start-closure.mjs needed a fix: the Start server entry is now itself a dynamic chunk, which put Start's own lazy loadEntries imports one hop further from the entry. Both hops are followed now.

Closure (node apps/cloud/scripts/start-closure.mjs apps/cloud/dist/server)

closure before after
startup 6.08 MB 5.25 MB
page request (startup + start) 9.86 MB 9.83 MB
API request (startup + app) 9.84 MB 9.06 MB

Verified with bun run --cwd apps/cloud typecheck, src/app-paths.test.ts, src/engine/execution-rate-limit.node.test.ts, src/api.request-scope.node.test.ts, and a production build. Not deployed.

Move the Start server entry, the MCP agent handler, the execution
rate-limit counter DO and the WorkOS events cron runner behind dynamic
imports so a cold isolate only evaluates what the path it serves needs.
Record executor.dispatch.graph_import_ms on worker.dispatch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 18, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 1dc1175 Commit Preview URL

Branch Preview URL
Sep 18 2026, 07:46 PM

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare preview

Console https://executor-preview-pr-2068.executor-e2e.workers.dev
MCP https://executor-preview-pr-2068.executor-e2e.workers.dev/mcp
Deployed commit 1dc1175

Sign-in is Cloudflare Access (one-time PIN to an allowed email). The preview has its own database and encryption key; it is destroyed when this PR closes.

@pkg-pr-new

pkg-pr-new Bot commented Sep 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@2068

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@2068

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@2068

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@2068

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@2068

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@2068

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@2068

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@2068

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@2068

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@2068

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@2068

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@2068

executor

npm i https://pkg.pr.new/executor@2068

commit: 1dc1175

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud 1dc1175 Sep 18 2026, 07:47 PM

This branch has not been deployed

No deployments
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