Repository navigation
perf(worker): the signing workflow stops dragging Zod into every cold start - #4
Merged
Merged
Conversation
… 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cherry-picked from
claude/sad-bose-8d1c02(665b0075), the one commit on that branch that does not collide with work already onmain.SignCompletionWorkflowmust 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 anawait import()at the one step that uses it. The class is still exported eagerly and still extendsWorkflowEntrypoint, 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.mjsmeasures — the Error 1102 gate added in5cf05963. The gate can see the improvement; nothing else in this change is user-visible.Provenance
claude/sad-bose-8d1c02is 8 commits ahead ofmainand 17 behind, and 18 files were changed on both lines. Seven of its eight commits are entangled in the photo viewer/annotator, whichmainhas since implemented independently (d295128c). This one touches onlyserver/workflows/sign-completion-workflow.tsand is clean.The remaining seven are not abandoned — they are salvage, to be reconciled against main's implementation rather than merged.
Type of change
Test plan
verifyreports on this PR — first run on actual code rather than docs[bundle-size] eager import closureline in the build jobPer the maintainer note in the PR template: merge, do not squash.
🤖 Generated with Claude Code