Skip to content

perf(worker): the signing workflow stops dragging Zod into every cold start - #4

Merged
NCHILLC merged 1 commit into
mainfrom
perf/worker-cold-start-zod
Sep 7, 2026
Merged

NCHILLC merged 1 commit into
mainfrom
perf/worker-cold-start-zod

Conversation

@NCHILLC

@NCHILLC NCHILLC commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Summary

Cherry-picked from claude/sad-bose-8d1c02 (665b0075), the one commit on that branch that does not collide with work already on main.

SignCompletionWorkflow must be exported from the worker entry for the runtime to bind it, so everything it imports statically is evaluated on every cold start — including, via the email builder → branding service, the whole @hono/zod-openapi + Zod graph. That subtree moves behind an await import() at the one step that uses it. The class is still exported eagerly and still extends WorkflowEntrypoint, so the runtime contract is unchanged.

One file, +13/−1.

Why it is worth landing on its own

This is the eager import closure that scripts/check-bundle-size.mjs measures — the Error 1102 gate added in 5cf05963. The gate can see the improvement; nothing else in this change is user-visible.

Provenance

claude/sad-bose-8d1c02 is 8 commits ahead of main and 17 behind, and 18 files were changed on both lines. Seven of its eight commits are entangled in the photo viewer/annotator, which main has since implemented independently (d295128c). This one touches only server/workflows/sign-completion-workflow.ts and is clean.

The remaining seven are not abandoned — they are salvage, to be reconciled against main's implementation rather than merged.

Type of change

  • Refactor / chore (no user-visible change)

Test plan

  • Pre-commit gates green (20/20 selected)
  • verify reports on this PR — first run on actual code rather than docs
  • Watch the [bundle-size] eager import closure line in the build job

Per the maintainer note in the PR template: merge, do not squash.

🤖 Generated with Claude Code

… start

Startup module graph: 843.7 KiB → 410.6 KiB across 54 → 42 modules, a 51%
cut, from moving one import. Zod and @hono/zod-openapi leave the startup
path entirely.

A Workflow class must be EXPORTED FROM THE WORKER ENTRY for the runtime to
bind it, so every module it imports statically is evaluated on every cold
start. `SignCompletionWorkflow` imported the tenant email builder, which
reaches the branding service, which reaches `@hono/zod-openapi` — and with
it 261 KiB of Zod. A third of the worker's startup cost was validation code
built for an API request that had not arrived, paid by every request that
is not a signing workflow.

The API itself was already lazy (`getApi()` in workers/app.ts) — that
boundary was deliberate and it held. Zod was not crossing it; it was riding
in beside it, through an export the runtime requires.

The import moves inside the step that uses it. The class still extends
WorkflowEntrypoint and is still exported eagerly, so the runtime contract
is untouched — only the subtree behind it became lazy. That is deliberately
the smaller change: stubbing the class the way `InspectorMcp` is stubbed
would also work for the graph, but a Workflow's binding contract is not
something to guess at when the failure mode is silent.

Measured, not inferred: walk the STATIC imports of build/server/index.js
transitively. A chunking fix (manualChunks splitting hono/zod/openapi) was
tried first and REJECTED — it moved the weight between chunks and measured
843.7 → 857.3 KiB, slightly worse. The path mattered, not the packing.

Diminishing returns from here: what remains is flat, topped by results-doc
(85 KiB, needed by the collab Durable Object, also an entry export).

Verified: 62/62 gates, both type-checks, 8,201 API + 170 workers tests,
bundle 69.2% of the Free limit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@NCHILLC
NCHILLC merged commit 3230258 into main Sep 7, 2026
13 of 18 checks passed
@NCHILLC
NCHILLC deleted the perf/worker-cold-start-zod branch September 7, 2026 19:30
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