Skip to content

feat(core): experimental start-hook admission for start()#2762

Draft
NathanColosimo wants to merge 1 commit into
mainfrom
nathan/start-hooks-01-core
Draft

feat(core): experimental start-hook admission for start()#2762
NathanColosimo wants to merge 1 commit into
mainfrom
nathan/start-hooks-01-core

Conversation

@NathanColosimo

@NathanColosimo NathanColosimo commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Stack 1/4 · this PR → #2763#2764#2765 · Replaces the monolithic #2684

Adds the experimental hook option to start() (refs #2376, gaps 1 and 2): Worlds that declare startHookAdmission reserve the hook token atomically with run admission, so duplicate starts are rejected before any duplicate workflow code can run.

const run = await start(processOrder, [orderId], {
  hook: {
    token: `order:${orderId}`,
    experimental_ttl: '30 days',
  },
});

What's in this PR

  • start() option + validation. Admission is queue-first everywhere: enqueue → admission (run_created claims the token). A crash after the enqueue cannot orphan a claimed token — the queued message bootstraps admission itself via the resilient run_started path. Admission failures after the enqueue surface as the new WorkflowStartError (runId / stage / queued / retryable); HookConflictError passes through.
  • experimental_ttl is optional: without it, the token is released when the hook is disposed or the run ends (plain-guard semantics); with it, the token stays fenced for the TTL past hook creation / run completion.
  • Queue failures on the default (non-hook) start() path are now also typed as WorkflowStartError (stage queue) instead of leaking raw transport errors — the create/queue parallelism is unchanged.
  • Runtime handling for queued runs that lost their claim: acknowledged without running user code; turbo mode disabled for start-hook runs. Gated cross-deployment by the new startHookLoserAck capability (cutoff 5.0.0-beta.27).
  • @workflow/world: World.startHookAdmission declaration, StartHook schema/type on run_created / resilient-start run_started / queue runInput (embedded directly in the queue runInput schema).
  • WorkflowStartError serialization end-to-end (core reducers/revivers, web-shared + CLI hydration).
  • world-vercel v4 wire routing only for the new eventData field — its compile-time wire-contract exhaustiveness guard requires schema fields to be routed in the same change. Vercel admission behavior lands in PR 4.
  • Docs: Idempotency foundations section, start() API notes, WorkflowStartError reference page.

No World in this PR implements admission yet — using the option against an unsupporting World throws a clear error. Implementations land in the stacked follow-ups.

Docs Preview

Preview links will resolve once the docs deployment builds for this branch: /v5/docs/foundations/idempotency#atomic-start-hook-idempotency, /v5/docs/api-reference/workflow-api/start, /v5/docs/api-reference/workflow-errors/workflow-start-error.

@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c413943

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 21 packages
Name Type
workflow Minor
@workflow/core Minor
@workflow/errors Minor
@workflow/world Minor
@workflow/web-shared Patch
@workflow/cli Patch
@workflow/world-vercel Patch
@workflow/world-testing Patch
@workflow/builders Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/vitest Patch
@workflow/web Patch
@workflow/world-local Patch
@workflow/world-postgres Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/nuxt Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview, Comment Jul 7, 2026 12:09am
example-nextjs-workflow-webpack Ready Ready Preview, Comment Jul 7, 2026 12:09am
example-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-astro-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-express-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-fastify-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-hono-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-nitro-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-nuxt-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-sveltekit-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-tanstack-start-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workbench-vite-workflow Ready Ready Preview, Comment Jul 7, 2026 12:09am
workflow-docs Ready Ready Preview, Comment, Open in v0 Jul 7, 2026 12:09am
workflow-swc-playground Ready Ready Preview, Comment Jul 7, 2026 12:09am
workflow-tarballs Ready Ready Preview, Comment Jul 7, 2026 12:09am
workflow-web Ready Ready Preview, Comment Jul 7, 2026 12:09am

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 1442 0 230 1672
✅ 💻 Local Development 1605 0 219 1824
✅ 📦 Local Production 1605 0 219 1824
✅ 🐘 Local Postgres 1605 0 219 1824
✅ 🪟 Windows 152 0 0 152
✅ 📋 Other 887 0 177 1064
Total 7296 0 1064 8360

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 125 0 27
✅ example 125 0 27
✅ express 125 0 27
✅ fastify 125 0 27
✅ hono 125 0 27
✅ nextjs-turbopack 149 0 3
✅ nextjs-webpack 149 0 3
✅ nitro 125 0 27
✅ nuxt 125 0 27
✅ sveltekit 144 0 8
✅ vite 125 0 27
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-turbopack-stable 152 0 0
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-turbopack-stable 152 0 0
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-turbopack-stable 152 0 0
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 152 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 127 0 25
✅ e2e-local-dev-tanstack-start- 127 0 25
✅ e2e-local-postgres-nest-stable 127 0 25
✅ e2e-local-postgres-tanstack-start- 127 0 25
✅ e2e-local-prod-nest-stable 127 0 25
✅ e2e-local-prod-tanstack-start- 127 0 25
✅ e2e-vercel-prod-tanstack-start 125 0 27

📋 View full workflow run

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

📈 Comparing against baseline from main branch. Green 🟢 = faster, Red 🔺 = slower.

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 0.045s (-2.8%) 1.006s (~) 0.961s 10 1.00x
💻 Local Next.js (Turbopack) 0.049s (-7.7% 🟢) 1.006s (~) 0.957s 10 1.09x
💻 Local Express 0.051s (+13.0% 🔺) 1.006s (~) 0.956s 10 1.12x
🐘 Postgres Nitro 0.068s (+4.0%) 1.013s (~) 0.944s 10 1.51x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 0.249s (+10.6% 🔺) 1.495s (-27.0% 🟢) 1.246s 10 1.00x
▲ Vercel Next.js (Turbopack) 0.558s (+129.6% 🔺) 2.365s (-0.6%) 1.806s 10 2.24x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.078s (~) 2.007s (~) 0.929s 10 1.00x
💻 Local Next.js (Turbopack) 1.082s (-0.7%) 2.006s (~) 0.924s 10 1.00x
💻 Local Express 1.086s (~) 2.007s (~) 0.921s 10 1.01x
🐘 Postgres Nitro 1.098s (~) 2.010s (~) 0.912s 10 1.02x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.498s (+5.7% 🔺) 2.718s (-3.7%) 1.220s 10 1.00x
▲ Vercel Next.js (Turbopack) 2.085s (-11.1% 🟢) 3.673s (+2.3%) 1.588s 10 1.39x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 10.438s (~) 11.022s (~) 0.584s 3 1.00x
🐘 Postgres Nitro 10.494s (~) 11.017s (~) 0.523s 3 1.01x
💻 Local Express 10.507s (~) 11.023s (~) 0.517s 3 1.01x
💻 Local Next.js (Turbopack) 10.518s (~) 11.022s (~) 0.504s 3 1.01x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 11.891s (+1.9%) 13.369s (-4.2%) 1.478s 3 1.00x
▲ Vercel Next.js (Turbopack) 13.437s (+4.0%) 15.696s (+10.7% 🔺) 2.259s 2 1.13x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 13.646s (~) 14.028s (~) 0.382s 5 1.00x
💻 Local Next.js (Turbopack) 13.663s (~) 14.026s (~) 0.362s 5 1.00x
🐘 Postgres Nitro 13.678s (~) 14.022s (~) 0.344s 5 1.00x
💻 Local Express 13.695s (~) 14.027s (~) 0.332s 5 1.00x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 16.128s (-3.3%) 18.034s (-4.8%) 1.905s 4 1.00x
▲ Vercel Next.js (Turbopack) 17.929s (~) 19.736s (~) 1.807s 4 1.11x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Next.js (Turbopack) 12.201s (~) 13.025s (~) 0.825s 7 1.00x
💻 Local Express 12.329s (+0.9%) 13.026s (~) 0.696s 7 1.01x
💻 Local Nitro 12.393s (+1.4%) 13.025s (~) 0.632s 7 1.02x
🐘 Postgres Nitro 12.396s (~) 13.020s (~) 0.624s 7 1.02x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 17.912s (+3.6%) 19.562s (+2.0%) 1.650s 5 1.00x
▲ Vercel Next.js (Turbopack) 20.563s (+4.4%) 21.989s (+1.4%) 1.426s 5 1.15x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.209s (+1.9%) 2.009s (~) 0.800s 15 1.00x
💻 Local Nitro 1.384s (-1.6%) 2.006s (~) 0.622s 15 1.15x
💻 Local Next.js (Turbopack) 1.401s (~) 2.006s (~) 0.604s 15 1.16x
💻 Local Express 1.411s (-2.3%) 2.007s (~) 0.596s 15 1.17x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.103s (-7.5% 🟢) 3.557s (-8.8% 🟢) 1.454s 9 1.00x
▲ Vercel Next.js (Turbopack) 3.572s (+21.6% 🔺) 5.147s (+10.9% 🔺) 1.574s 6 1.70x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.342s (-4.1%) 2.738s (+10.8% 🔺) 1.396s 11 1.00x
💻 Local Nitro 2.376s (+2.4%) 3.009s (~) 0.633s 10 1.77x
💻 Local Next.js (Turbopack) 2.425s (-2.6%) 3.008s (-3.2%) 0.584s 10 1.81x
💻 Local Express 2.598s (-2.2%) 3.110s (~) 0.512s 10 1.94x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.728s (+4.7%) 4.046s (-1.8%) 1.318s 8 1.00x
▲ Vercel Next.js (Turbopack) 4.202s (+26.2% 🔺) 5.780s (+17.8% 🔺) 1.578s 6 1.54x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.615s (-0.9%) 4.297s (+3.8%) 2.683s 7 1.00x
💻 Local Next.js (Turbopack) 2.833s (-39.7% 🟢) 4.583s (-16.9% 🟢) 1.750s 7 1.75x
💻 Local Nitro 4.467s (+4.0%) 5.179s (+6.3% 🔺) 0.712s 6 2.77x
💻 Local Express 4.486s (+1.6%) 5.346s (+3.2%) 0.860s 6 2.78x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.139s (+7.5% 🔺) 4.923s (+12.1% 🔺) 1.784s 7 1.00x
▲ Vercel Next.js (Turbopack) 4.606s (+16.6% 🔺) 6.305s (+9.2% 🔺) 1.699s 5 1.47x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.188s (-0.7%) 2.008s (~) 0.820s 15 1.00x
💻 Local Nitro 1.427s (+0.9%) 2.007s (~) 0.580s 15 1.20x
💻 Local Next.js (Turbopack) 1.429s (-4.8%) 2.006s (~) 0.578s 15 1.20x
💻 Local Express 1.471s (+1.2%) 2.006s (~) 0.535s 15 1.24x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.196s (+13.6% 🔺) 3.633s (-0.6%) 1.437s 9 1.00x
▲ Vercel Next.js (Turbopack) 4.180s (+40.6% 🔺) 5.529s (+17.5% 🔺) 1.349s 6 1.90x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.373s (+4.1%) 2.760s (+37.5% 🔺) 1.387s 12 1.00x
💻 Local Nitro 2.473s (+1.2%) 3.009s (~) 0.536s 10 1.80x
💻 Local Next.js (Turbopack) 2.493s (-11.3% 🟢) 3.008s (-10.0% 🟢) 0.515s 10 1.82x
💻 Local Express 2.607s (+4.7%) 3.009s (~) 0.402s 10 1.90x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.438s (-21.4% 🟢) 3.769s (-17.7% 🟢) 1.331s 8 1.00x
▲ Vercel Next.js (Turbopack) 3.768s (+19.4% 🔺) 5.095s (+12.3% 🔺) 1.327s 7 1.55x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.638s (~) 4.137s (-3.8%) 2.498s 8 1.00x
💻 Local Express 5.423s (+52.0% 🔺) 6.016s (+20.0% 🔺) 0.593s 5 3.31x
💻 Local Nitro 5.656s (+2.4%) 6.216s (+3.3%) 0.560s 5 3.45x
💻 Local Next.js (Turbopack) 5.707s (+5.6% 🔺) 6.014s (~) 0.307s 5 3.48x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.993s (+12.4% 🔺) 4.780s (+7.8% 🔺) 1.787s 7 1.00x
▲ Vercel Next.js (Turbopack) 5.521s (+22.4% 🔺) 7.147s (+16.4% 🔺) 1.627s 5 1.84x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 0.571s (-2.2%) 1.005s (~) 0.433s 60 1.00x
🐘 Postgres Nitro 0.603s (~) 1.024s (~) 0.421s 59 1.05x
💻 Local Next.js (Turbopack) 0.616s (+2.8%) 1.005s (~) 0.389s 60 1.08x
💻 Local Express 0.629s (+4.0%) 1.005s (~) 0.376s 60 1.10x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.777s (+11.6% 🔺) 4.145s (+4.5%) 1.368s 15 1.00x
▲ Vercel Next.js (Turbopack) 4.028s (-0.6%) 5.531s (-2.3%) 1.503s 11 1.45x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.400s (~) 2.030s (~) 0.630s 45 1.00x
💻 Local Nitro 1.434s (-0.9%) 2.006s (~) 0.572s 45 1.02x
💻 Local Next.js (Turbopack) 1.514s (-3.8%) 2.006s (~) 0.492s 45 1.08x
💻 Local Express 1.520s (+1.8%) 2.006s (~) 0.486s 45 1.09x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 5.832s (~) 7.389s (-1.2%) 1.557s 13 1.00x
▲ Vercel Next.js (Turbopack) 8.915s (+8.1% 🔺) 10.797s (+12.6% 🔺) 1.882s 9 1.53x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 2.830s (-0.6%) 3.138s (-2.5%) 0.308s 39 1.00x
💻 Local Nitro 3.188s (~) 3.853s (-2.3%) 0.664s 32 1.13x
💻 Local Next.js (Turbopack) 3.360s (-2.1%) 4.043s (+0.8%) 0.683s 30 1.19x
💻 Local Express 3.430s (+3.0%) 4.043s (+0.8%) 0.612s 30 1.21x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 11.625s (-0.6%) 13.492s (-2.5%) 1.867s 9 1.00x
▲ Vercel Next.js (Turbopack) 17.288s (+0.9%) 19.278s (+3.0%) 1.990s 7 1.49x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.235s (+6.5% 🔺) 1.007s (~) 0.771s 60 1.00x
💻 Local Nitro 0.514s (~) 1.005s (~) 0.490s 60 2.19x
💻 Local Express 0.541s (+4.8%) 1.022s (+1.7%) 0.481s 59 2.30x
💻 Local Next.js (Turbopack) 0.608s (-5.3% 🟢) 1.005s (-1.7%) 0.396s 60 2.59x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.180s (+4.8%) 2.832s (+7.7% 🔺) 1.652s 22 1.00x
▲ Vercel Next.js (Turbopack) 2.381s (+21.6% 🔺) 3.941s (+17.4% 🔺) 1.560s 16 2.02x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.359s (+2.4%) 1.006s (~) 0.648s 90 1.00x
💻 Local Express 2.498s (-1.3%) 3.042s (~) 0.545s 30 6.96x
💻 Local Nitro 2.541s (+0.6%) 3.009s (~) 0.468s 30 7.09x
💻 Local Next.js (Turbopack) 2.629s (-4.3%) 3.008s (-4.4%) 0.379s 30 7.33x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.495s (+4.9%) 3.278s (+7.4% 🔺) 1.783s 28 1.00x
▲ Vercel Next.js (Turbopack) 2.969s (+14.6% 🔺) 4.876s (+20.1% 🔺) 1.906s 19 1.99x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.605s (+5.6% 🔺) 1.108s (+2.9%) 0.503s 109 1.00x
💻 Local Nitro 5.611s (-4.1%) 8.669s (~) 3.058s 14 9.27x
💻 Local Express 5.677s (-5.1% 🟢) 8.810s (+3.8%) 3.133s 14 9.38x
💻 Local Next.js (Turbopack) 6.254s (-2.7%) 8.953s (-3.1%) 2.699s 14 10.33x
🐘 Postgres Express ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.910s (+19.0% 🔺) 4.086s (+12.3% 🔺) 2.176s 30 1.00x
▲ Vercel Next.js (Turbopack) 4.814s (+14.6% 🔺) 6.673s (+16.5% 🔺) 1.859s 18 2.52x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Next.js (Turbopack) 1.141s (~) 1.968s (~) 0.010s (+1.0%) 2.018s (~) 0.877s 10 1.00x
💻 Local Nitro 1.169s (+1.2%) 2.004s (~) 0.011s (~) 2.018s (~) 0.849s 10 1.02x
🐘 Postgres Nitro 1.171s (+0.8%) 1.999s (~) 0.001s (+16.7% 🔺) 2.011s (~) 0.840s 10 1.03x
💻 Local Express 1.172s (+0.9%) 2.004s (~) 0.012s (+8.8% 🔺) 2.020s (~) 0.847s 10 1.03x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.997s (+5.7% 🔺) 8.489s (+162.2% 🔺) 0.355s (-78.3% 🟢) 9.306s (+74.1% 🔺) 7.308s 10 1.00x
▲ Vercel Next.js (Turbopack) 3.637s (+14.1% 🔺) 9.324s (+166.5% 🔺) 0.401s (-72.5% 🟢) 10.728s (+66.7% 🔺) 7.091s 10 1.82x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Express | Next.js (Turbopack)

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.542s (-2.6%) 2.009s (-1.5%) 0.013s (-4.0%) 2.026s (-1.6%) 0.484s 30 1.00x
💻 Local Next.js (Turbopack) 1.578s (-1.4%) 1.971s (~) 0.012s (-3.3%) 2.025s (~) 0.447s 30 1.02x
💻 Local Express 1.582s (~) 2.011s (~) 0.013s (+9.0% 🔺) 2.026s (~) 0.444s 30 1.03x
🐘 Postgres Nitro 1.635s (~) 2.004s (~) 0.005s (-2.6%) 2.028s (~) 0.392s 30 1.06x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 5.539s (+2.0%) 7.467s (+5.9% 🔺) 0.184s (-17.4% 🟢) 8.136s (+4.6%) 2.597s 8 1.00x
▲ Vercel Next.js (Turbopack) 10.301s (+8.3% 🔺) 11.809s (+12.1% 🔺) 0.186s (-15.0% 🟢) 12.683s (+9.8% 🔺) 2.382s 5 1.86x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Express | Next.js (Turbopack)

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.804s (-5.1% 🟢) 1.082s (-3.6%) 0.000s (+183.9% 🔺) 1.097s (-3.9%) 0.293s 56 1.00x
💻 Local Nitro 1.289s (-4.5%) 1.918s (-1.6%) 0.000s (+29.2% 🔺) 1.921s (-1.5%) 0.633s 32 1.60x
💻 Local Next.js (Turbopack) 1.320s (-5.7% 🟢) 1.981s (~) 0.000s (-36.8% 🟢) 2.017s (~) 0.697s 30 1.64x
💻 Local Express 1.357s (~) 1.919s (~) 0.000s (+12.5% 🔺) 1.922s (~) 0.565s 32 1.69x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.218s (-38.4% 🟢) 4.775s (-27.8% 🟢) 0.000s (-75.0% 🟢) 5.287s (-26.0% 🟢) 2.069s 12 1.00x
▲ Vercel Next.js (Turbopack) 4.725s (+5.1% 🔺) 5.716s (+5.8% 🔺) 0.000s (NaN%) 6.733s (+9.1% 🔺) 2.008s 9 1.47x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Express | Next.js (Turbopack)

fan-out fan-in 10 streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.820s (+2.2%) 2.342s (-3.1%) 0.000s (+Infinity% 🔺) 2.356s (-3.2%) 0.536s 26 1.00x
💻 Local Nitro 3.344s (+3.1%) 3.963s (+1.6%) 0.001s (~) 3.968s (+1.6%) 0.623s 16 1.84x
💻 Local Next.js (Turbopack) 3.370s (-2.6%) 3.991s (~) 0.001s (-35.3% 🟢) 4.029s (~) 0.659s 15 1.85x
💻 Local Express 3.426s (+3.2%) 4.028s (+3.2%) 0.001s (+468.9% 🔺) 4.032s (+3.2%) 0.605s 15 1.88x
🐘 Postgres Express ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 4.571s (+1.8%) 6.015s (+5.6% 🔺) 0.000s (+Infinity% 🔺) 6.499s (+5.5% 🔺) 1.927s 10 1.00x
▲ Vercel Next.js (Turbopack) 7.449s (+1.2%) 8.576s (+9.8% 🔺) 0.000s (NaN%) 9.605s (+7.4% 🔺) 2.156s 7 1.63x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Express | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Nitro 16/21
🐘 Postgres Nitro 21/21
▲ Vercel Express 21/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 💻 Local 16/21
Next.js (Turbopack) 💻 Local 19/21
Nitro 🐘 Postgres 13/21
Column Definitions
  • Workflow Time: Runtime reported by workflow (completedAt - createdAt) - primary metric
  • TTFB: Time to First Byte - time from workflow start until first stream byte received (stream benchmarks only)
  • Slurp: Time from first byte to complete stream consumption (stream benchmarks only)
  • Wall Time: Total testbench time (trigger workflow + poll for result)
  • Overhead: Testbench overhead (Wall Time - Workflow Time)
  • Samples: Number of benchmark iterations run
  • vs Fastest: How much slower compared to the fastest configuration for this benchmark

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Redis + BullMQ: Community world (local development)
  • 🌐 Cloudflare: Community world (local development)
  • 🌐 MySQL: Community world (local development)
  • 🌐 Azure: Community world (local development)
  • 🌐 NATS JetStream: Community world (local development)
  • 🌐 Upstash: Community world (local development)
  • 🌐 Platformatic: Community world (local development)

📋 View full workflow run


Some benchmark jobs failed:

  • Local: success
  • Postgres: cancelled
  • Vercel: failure

Check the workflow run for details.

@NathanColosimo NathanColosimo force-pushed the nathan/start-hooks-01-core branch from 79beb9d to 41bdb5a Compare July 2, 2026 23:45
@NathanColosimo NathanColosimo force-pushed the nathan/start-hooks-01-core branch from 8438b93 to 7916e94 Compare July 6, 2026 20:11
@NathanColosimo NathanColosimo force-pushed the nathan/start-hooks-01-core branch from 7916e94 to f2c69fc Compare July 6, 2026 21:03
Adds the experimentalStartHook option to start(): Worlds that declare
experimentalStartHookAdmission (event-first or queue-first) reserve the
hook token atomically with run admission. Duplicate starts throw
HookConflictError; queue-first Worlds throw the new WorkflowStartError
(runId/stage/retryable) when a run was queued but admission could not
be confirmed. Turbo mode is disabled for start-hook runs and a queued
run that lost its claim acknowledges without running user code, gated
by the experimentalStartHookLoserAck capability.

world-vercel's v4 wire routing carries the new run_created /
resilient-start eventData field (its compile-time wire-contract guard
requires schema fields to be routed in the same change); the Vercel
admission behavior itself, and the local/postgres implementations, land
in the stacked follow-ups.
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