Skip to content

[world-local] Enforce hook token uniqueness and atomicity, matches other worlds#1348

Merged
VaguelySerious merged 3 commits intomainfrom
peter/local-storage-hook-race
Mar 12, 2026
Merged

[world-local] Enforce hook token uniqueness and atomicity, matches other worlds#1348
VaguelySerious merged 3 commits intomainfrom
peter/local-storage-hook-race

Conversation

@VaguelySerious
Copy link
Member

No description provided.

…her worlds

Signed-off-by: Peter Wielander <mittgfu@gmail.com>
@VaguelySerious VaguelySerious requested a review from a team as a code owner March 12, 2026 17:43
@vercel
Copy link
Contributor

vercel bot commented Mar 12, 2026

@github-actions
Copy link
Contributor

github-actions bot commented Mar 12, 2026

🧪 E2E Test Results

Some tests failed

Summary

Passed Failed Skipped Total
❌ ▲ Vercel Production 570 1 67 638
✅ 💻 Local Development 612 0 84 696
✅ 📦 Local Production 612 0 84 696
✅ 🐘 Local Postgres 612 0 84 696
✅ 🪟 Windows 55 0 3 58
❌ 🌍 Community Worlds 118 56 15 189
✅ 📋 Other 147 0 27 174
Total 2726 57 364 3147

❌ Failed Tests

▲ Vercel Production (1 failed)

nextjs-turbopack (1 failed):

  • error handling retry behavior workflow completes despite transient 5xx on step_completed
🌍 Community Worlds (56 failed)

mongodb (3 failed):

  • hookWorkflow is not resumable via public webhook endpoint
  • webhookWorkflow
  • concurrent hook token conflict - two workflows cannot use the same hook token simultaneously

redis (2 failed):

  • hookWorkflow is not resumable via public webhook endpoint
  • concurrent hook token conflict - two workflows cannot use the same hook token simultaneously

turso (51 failed):

  • addTenWorkflow
  • addTenWorkflow
  • wellKnownAgentWorkflow (.well-known/agent)
  • should work with react rendering in step
  • promiseAllWorkflow
  • promiseRaceWorkflow
  • promiseAnyWorkflow
  • importedStepOnlyWorkflow
  • hookWorkflow
  • hookWorkflow is not resumable via public webhook endpoint
  • webhookWorkflow
  • sleepingWorkflow
  • parallelSleepWorkflow
  • nullByteWorkflow
  • workflowAndStepMetadataWorkflow
  • fetchWorkflow
  • promiseRaceStressTestWorkflow
  • error handling error propagation workflow errors nested function calls preserve message and stack trace
  • error handling error propagation workflow errors cross-file imports preserve message and stack trace
  • error handling error propagation step errors basic step error preserves message and stack trace
  • error handling error propagation step errors cross-file step error preserves message and function names in stack
  • error handling retry behavior regular Error retries until success
  • error handling retry behavior FatalError fails immediately without retries
  • error handling retry behavior RetryableError respects custom retryAfter delay
  • error handling retry behavior maxRetries=0 disables retries
  • error handling retry behavior workflow completes despite transient 5xx on step_completed
  • error handling catchability FatalError can be caught and detected with FatalError.is()
  • hookCleanupTestWorkflow - hook token reuse after workflow completion
  • concurrent hook token conflict - two workflows cannot use the same hook token simultaneously
  • hookDisposeTestWorkflow - hook token reuse after explicit disposal while workflow still running
  • stepFunctionPassingWorkflow - step function references can be passed as arguments (without closure vars)
  • stepFunctionWithClosureWorkflow - step function with closure variables passed as argument
  • closureVariableWorkflow - nested step functions with closure variables
  • spawnWorkflowFromStepWorkflow - spawning a child workflow using start() inside a step
  • health check (queue-based) - workflow and step endpoints respond to health check messages
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly
  • Calculator.calculate - static workflow method using static step methods from another class
  • AllInOneService.processNumber - static workflow method using sibling static step methods
  • ChainableService.processWithThis - static step methods using this to reference the class
  • thisSerializationWorkflow - step function invoked with .call() and .apply()
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE
  • instanceMethodStepWorkflow - instance methods with "use step" directive
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument
  • cancelRun - cancelling a running workflow
  • cancelRun via CLI - cancelling a running workflow
  • pages router addTenWorkflow via pages router
  • pages router promiseAllWorkflow via pages router
  • pages router sleepingWorkflow via pages router
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control)

Details by Category

❌ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 51 0 7
✅ example 51 0 7
✅ express 51 0 7
✅ fastify 51 0 7
✅ hono 51 0 7
❌ nextjs-turbopack 55 1 2
✅ nextjs-webpack 56 0 2
✅ nitro 51 0 7
✅ nuxt 51 0 7
✅ sveltekit 51 0 7
✅ vite 51 0 7
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 49 0 9
✅ express-stable 49 0 9
✅ fastify-stable 49 0 9
✅ hono-stable 49 0 9
✅ nextjs-turbopack-canary 55 0 3
✅ nextjs-turbopack-stable 55 0 3
✅ nextjs-webpack-canary 55 0 3
✅ nextjs-webpack-stable 55 0 3
✅ nitro-stable 49 0 9
✅ nuxt-stable 49 0 9
✅ sveltekit-stable 49 0 9
✅ vite-stable 49 0 9
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 49 0 9
✅ express-stable 49 0 9
✅ fastify-stable 49 0 9
✅ hono-stable 49 0 9
✅ nextjs-turbopack-canary 55 0 3
✅ nextjs-turbopack-stable 55 0 3
✅ nextjs-webpack-canary 55 0 3
✅ nextjs-webpack-stable 55 0 3
✅ nitro-stable 49 0 9
✅ nuxt-stable 49 0 9
✅ sveltekit-stable 49 0 9
✅ vite-stable 49 0 9
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 49 0 9
✅ express-stable 49 0 9
✅ fastify-stable 49 0 9
✅ hono-stable 49 0 9
✅ nextjs-turbopack-canary 55 0 3
✅ nextjs-turbopack-stable 55 0 3
✅ nextjs-webpack-canary 55 0 3
✅ nextjs-webpack-stable 55 0 3
✅ nitro-stable 49 0 9
✅ nuxt-stable 49 0 9
✅ sveltekit-stable 49 0 9
✅ vite-stable 49 0 9
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 55 0 3
❌ 🌍 Community Worlds
App Passed Failed Skipped
✅ mongodb-dev 3 0 2
❌ mongodb 52 3 3
✅ redis-dev 3 0 2
❌ redis 53 2 3
✅ turso-dev 3 0 2
❌ turso 4 51 3
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 49 0 9
✅ e2e-local-postgres-nest-stable 49 0 9
✅ e2e-local-prod-nest-stable 49 0 9

📋 View full workflow run


Some E2E test jobs failed:

  • Vercel Prod: failure
  • Local Dev: success
  • Local Prod: success
  • Local Postgres: success
  • Windows: success

Check the workflow run for details.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 12, 2026

📊 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 🥇 Express 0.034s (+4.0%) 1.006s (~) 0.972s 10 1.00x
💻 Local Nitro 0.034s (+2.1%) 1.006s (~) 0.972s 10 1.01x
💻 Local Next.js (Turbopack) 0.041s (~) 1.005s (~) 0.963s 10 1.24x
🌐 Redis Next.js (Turbopack) 0.045s (-1.3%) 1.005s (~) 0.959s 10 1.36x
🐘 Postgres Nitro 0.051s (+15.5% 🔺) 1.012s (~) 0.960s 10 1.53x
🐘 Postgres Express 0.053s (-2.0%) 1.012s (~) 0.958s 10 1.59x
🐘 Postgres Next.js (Turbopack) 0.056s (+3.5%) 1.012s (~) 0.957s 10 1.67x
🌐 MongoDB Next.js (Turbopack) 0.082s (-13.7% 🟢) 1.008s (~) 0.926s 10 2.46x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 0.457s (+19.0% 🔺) 2.329s (+15.9% 🔺) 1.872s 10 1.00x
▲ Vercel Express 0.472s (-6.1% 🟢) 2.384s (+14.4% 🔺) 1.912s 10 1.03x
▲ Vercel Next.js (Turbopack) 0.759s (+53.7% 🔺) 2.839s (+17.3% 🔺) 2.080s 10 1.66x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 1.104s (-0.9%) 2.006s (~) 0.903s 10 1.00x
💻 Local Express 1.106s (~) 2.006s (~) 0.899s 10 1.00x
💻 Local Next.js (Turbopack) 1.107s (~) 2.005s (~) 0.898s 10 1.00x
💻 Local Nitro 1.108s (~) 2.006s (~) 0.898s 10 1.00x
🐘 Postgres Express 1.125s (-1.7%) 2.012s (~) 0.888s 10 1.02x
🐘 Postgres Next.js (Turbopack) 1.126s (~) 2.013s (~) 0.887s 10 1.02x
🐘 Postgres Nitro 1.130s (+2.5%) 2.013s (~) 0.883s 10 1.02x
🌐 MongoDB Next.js (Turbopack) 1.307s (~) 2.009s (~) 0.701s 10 1.18x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.055s (-2.5%) 4.495s (+22.6% 🔺) 2.440s 10 1.00x
▲ Vercel Next.js (Turbopack) 2.074s (+3.4%) 5.325s (+49.6% 🔺) 3.251s 10 1.01x
▲ Vercel Nitro 2.123s (+3.9%) 4.684s (+46.6% 🔺) 2.561s 10 1.03x

🔍 Observability: Express | Next.js (Turbopack) | Nitro

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 10.654s (~) 11.023s (~) 0.369s 3 1.00x
💻 Local Next.js (Turbopack) 10.679s (~) 11.022s (~) 0.344s 3 1.00x
💻 Local Express 10.807s (~) 11.023s (~) 0.216s 3 1.01x
🐘 Postgres Next.js (Turbopack) 10.821s (~) 11.048s (~) 0.227s 3 1.02x
💻 Local Nitro 10.830s (~) 11.023s (~) 0.194s 3 1.02x
🐘 Postgres Nitro 10.849s (+1.5%) 11.045s (~) 0.197s 3 1.02x
🐘 Postgres Express 10.856s (~) 11.043s (~) 0.187s 3 1.02x
🌐 MongoDB Next.js (Turbopack) 12.206s (~) 13.018s (~) 0.812s 3 1.15x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 16.709s (~) 20.641s (+11.2% 🔺) 3.932s 2 1.00x
▲ Vercel Nitro 16.963s (+2.5%) 19.308s (+9.0% 🔺) 2.345s 2 1.02x
▲ Vercel Next.js (Turbopack) 19.012s (+13.0% 🔺) 20.953s (+12.1% 🔺) 1.941s 2 1.14x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 26.560s (~) 27.049s (~) 0.489s 3 1.00x
🐘 Postgres Next.js (Turbopack) 26.895s (-0.6%) 27.063s (-1.3%) 0.169s 3 1.01x
🐘 Postgres Express 26.930s (~) 27.057s (~) 0.127s 3 1.01x
💻 Local Next.js (Turbopack) 26.973s (~) 27.049s (~) 0.076s 3 1.02x
🐘 Postgres Nitro 27.017s (+1.5%) 27.402s (+1.2%) 0.385s 3 1.02x
💻 Local Express 27.267s (~) 28.054s (~) 0.787s 3 1.03x
💻 Local Nitro 27.284s (~) 28.052s (~) 0.768s 3 1.03x
🌐 MongoDB Next.js (Turbopack) 30.496s (~) 31.042s (~) 0.546s 2 1.15x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 43.593s (+2.6%) 44.774s (+1.2%) 1.182s 2 1.00x
▲ Vercel Nitro 44.740s (+5.8% 🔺) 47.552s (+9.9% 🔺) 2.812s 2 1.03x
▲ Vercel Next.js (Turbopack) 44.927s (+5.9% 🔺) 46.744s (+5.6% 🔺) 1.817s 2 1.03x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 53.150s (~) 53.596s (-0.9%) 0.446s 2 1.00x
🐘 Postgres Next.js (Turbopack) 53.846s (~) 54.104s (~) 0.258s 2 1.01x
🐘 Postgres Express 53.901s (~) 54.103s (~) 0.202s 2 1.01x
🐘 Postgres Nitro 54.007s (+1.6%) 54.106s (~) 0.099s 2 1.02x
💻 Local Next.js (Turbopack) 55.565s (~) 56.101s (~) 0.536s 2 1.05x
💻 Local Nitro 56.099s (~) 56.600s (~) 0.500s 2 1.06x
💻 Local Express 56.398s (+0.7%) 57.108s (+1.8%) 0.710s 2 1.06x
🌐 MongoDB Next.js (Turbopack) 60.910s (~) 61.074s (~) 0.164s 2 1.15x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 96.829s (+3.2%) 98.300s (+2.7%) 1.471s 1 1.00x
▲ Vercel Nitro 96.929s (+3.1%) 98.223s (+3.6%) 1.294s 1 1.00x
▲ Vercel Express 100.205s (+6.6% 🔺) 101.919s (+6.7% 🔺) 1.714s 1 1.03x

🔍 Observability: Next.js (Turbopack) | Nitro | Express

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 1.258s (+1.6%) 2.006s (~) 0.748s 15 1.00x
🐘 Postgres Nitro 1.338s (+3.4%) 2.011s (~) 0.672s 15 1.06x
🐘 Postgres Express 1.366s (~) 2.011s (~) 0.645s 15 1.09x
🐘 Postgres Next.js (Turbopack) 1.382s (-1.8%) 2.011s (~) 0.628s 15 1.10x
💻 Local Nitro 1.406s (~) 2.006s (~) 0.600s 15 1.12x
💻 Local Next.js (Turbopack) 1.407s (~) 2.005s (~) 0.598s 15 1.12x
💻 Local Express 1.445s (+3.9%) 2.006s (~) 0.561s 15 1.15x
🌐 MongoDB Next.js (Turbopack) 2.146s (~) 3.009s (~) 0.862s 10 1.71x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.128s (-15.3% 🟢) 3.676s (-10.3% 🟢) 1.548s 9 1.00x
▲ Vercel Next.js (Turbopack) 2.556s (+6.6% 🔺) 4.016s (+6.9% 🔺) 1.460s 8 1.20x
▲ Vercel Nitro 2.588s (+15.9% 🔺) 3.992s (+20.9% 🔺) 1.404s 8 1.22x

🔍 Observability: Express | Next.js (Turbopack) | Nitro

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 2.457s (~) 3.012s (~) 0.555s 10 1.00x
🐘 Postgres Nitro 2.483s (~) 3.013s (~) 0.530s 10 1.01x
🌐 Redis Next.js (Turbopack) 2.491s (-0.8%) 3.008s (~) 0.517s 10 1.01x
💻 Local Next.js (Turbopack) 2.536s (+2.9%) 3.007s (~) 0.471s 10 1.03x
🐘 Postgres Next.js (Turbopack) 2.572s (-1.6%) 3.016s (~) 0.444s 10 1.05x
💻 Local Nitro 2.575s (-4.2%) 3.007s (~) 0.432s 10 1.05x
💻 Local Express 2.762s (+6.0% 🔺) 3.009s (~) 0.247s 10 1.12x
🌐 MongoDB Next.js (Turbopack) 4.615s (-1.0%) 5.177s (~) 0.562s 6 1.88x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.574s (-2.4%) 3.787s (-2.4%) 1.214s 8 1.00x
▲ Vercel Express 2.890s (+9.0% 🔺) 4.424s (+8.3% 🔺) 1.534s 7 1.12x
▲ Vercel Next.js (Turbopack) 3.196s (+8.5% 🔺) 4.704s (+9.5% 🔺) 1.508s 7 1.24x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 3.938s (-1.4%) 4.309s (-3.2%) 0.371s 7 1.00x
🐘 Postgres Nitro 3.981s (-1.9%) 4.445s (-6.1% 🟢) 0.464s 7 1.01x
🌐 Redis Next.js (Turbopack) 4.090s (+1.5%) 4.868s (+3.0%) 0.778s 7 1.04x
🐘 Postgres Next.js (Turbopack) 4.311s (+3.9%) 5.018s (~) 0.707s 6 1.09x
💻 Local Nitro 6.920s (-13.4% 🟢) 7.218s (-12.7% 🟢) 0.298s 5 1.76x
💻 Local Next.js (Turbopack) 7.096s (+6.7% 🔺) 7.516s (+4.2%) 0.420s 4 1.80x
💻 Local Express 8.341s (+8.9% 🔺) 8.770s (+6.1% 🔺) 0.428s 4 2.12x
🌐 MongoDB Next.js (Turbopack) 9.866s (-1.5%) 10.352s (~) 0.485s 3 2.51x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.050s (-7.8% 🟢) 4.489s (+2.1%) 1.439s 7 1.00x
▲ Vercel Nitro 3.388s (+10.7% 🔺) 4.550s (-1.4%) 1.162s 7 1.11x
▲ Vercel Next.js (Turbopack) 3.546s (+12.9% 🔺) 4.997s (+4.9%) 1.451s 7 1.16x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 1.295s (+5.9% 🔺) 2.007s (~) 0.711s 15 1.00x
🐘 Postgres Nitro 1.336s (-2.3%) 2.011s (~) 0.675s 15 1.03x
🐘 Postgres Express 1.345s (-0.8%) 2.010s (~) 0.665s 15 1.04x
🐘 Postgres Next.js (Turbopack) 1.422s (+2.4%) 2.011s (~) 0.589s 15 1.10x
💻 Local Next.js (Turbopack) 1.432s (+1.4%) 2.005s (~) 0.574s 15 1.11x
💻 Local Nitro 1.436s (-0.9%) 2.005s (~) 0.569s 15 1.11x
💻 Local Express 1.439s (-2.3%) 2.007s (~) 0.568s 15 1.11x
🌐 MongoDB Next.js (Turbopack) 2.180s (~) 3.007s (~) 0.828s 10 1.68x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.317s (-8.5% 🟢) 4.006s (-2.1%) 1.689s 8 1.00x
▲ Vercel Next.js (Turbopack) 2.356s (-3.2%) 3.689s (-10.6% 🟢) 1.333s 9 1.02x
▲ Vercel Nitro 2.567s (-1.2%) 4.041s (+10.1% 🔺) 1.474s 8 1.11x

🔍 Observability: Express | Next.js (Turbopack) | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 2.447s (-2.7%) 3.011s (~) 0.564s 10 1.00x
🐘 Postgres Nitro 2.479s (-4.9%) 3.013s (-3.2%) 0.534s 10 1.01x
🌐 Redis Next.js (Turbopack) 2.508s (~) 3.008s (~) 0.500s 10 1.02x
🐘 Postgres Next.js (Turbopack) 2.556s (-4.2%) 3.012s (~) 0.457s 10 1.04x
💻 Local Nitro 2.622s (-4.6%) 3.008s (~) 0.386s 10 1.07x
💻 Local Next.js (Turbopack) 2.734s (+4.1%) 3.008s (~) 0.273s 10 1.12x
💻 Local Express 2.847s (+1.4%) 3.008s (~) 0.161s 10 1.16x
🌐 MongoDB Next.js (Turbopack) 4.669s (-1.1%) 5.178s (~) 0.509s 6 1.91x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.624s (+1.2%) 3.917s (~) 1.293s 8 1.00x
▲ Vercel Nitro 2.636s (+2.4%) 3.851s (+10.4% 🔺) 1.215s 8 1.00x
▲ Vercel Express 2.660s (+11.4% 🔺) 3.998s (+5.1% 🔺) 1.337s 8 1.01x

🔍 Observability: Next.js (Turbopack) | Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 3.965s (-2.1%) 4.590s (-5.8% 🟢) 0.624s 7 1.00x
🐘 Postgres Express 4.000s (-0.8%) 4.444s (-3.1%) 0.445s 7 1.01x
🌐 Redis Next.js (Turbopack) 4.048s (-0.7%) 4.439s (-8.8% 🟢) 0.391s 7 1.02x
🐘 Postgres Next.js (Turbopack) 4.132s (-4.9%) 5.017s (~) 0.885s 6 1.04x
💻 Local Nitro 7.449s (-7.1% 🟢) 8.022s (-8.5% 🟢) 0.573s 4 1.88x
💻 Local Next.js (Turbopack) 7.460s (-3.4%) 8.018s (~) 0.558s 4 1.88x
💻 Local Express 8.629s (+8.2% 🔺) 9.021s (+9.1% 🔺) 0.392s 4 2.18x
🌐 MongoDB Next.js (Turbopack) 9.960s (~) 10.347s (-3.2%) 0.387s 3 2.51x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.821s (-1.7%) 4.230s (+2.8%) 1.409s 8 1.00x
▲ Vercel Nitro 2.925s (+5.8% 🔺) 4.332s (+15.2% 🔺) 1.406s 8 1.04x
▲ Vercel Next.js (Turbopack) 3.221s (-1.0%) 4.629s (+4.9%) 1.407s 7 1.14x

🔍 Observability: Express | Nitro | 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) 0.140s (~) 1.002s (~) 0.012s (+7.3% 🔺) 1.018s (~) 0.878s 10 1.00x
🌐 Redis Next.js (Turbopack) 0.146s (-0.6%) 1.000s (~) 0.001s (-6.7% 🟢) 1.008s (~) 0.862s 10 1.04x
💻 Local Nitro 0.177s (+3.6%) 1.003s (~) 0.010s (-12.9% 🟢) 1.016s (~) 0.839s 10 1.27x
💻 Local Express 0.180s (+5.5% 🔺) 1.002s (~) 0.012s (+9.9% 🔺) 1.018s (~) 0.839s 10 1.28x
🐘 Postgres Next.js (Turbopack) 0.183s (-1.9%) 1.001s (~) 0.001s (-7.1% 🟢) 1.012s (~) 0.830s 10 1.31x
🐘 Postgres Express 0.185s (-1.2%) 0.997s (~) 0.002s (-6.3% 🟢) 1.012s (~) 0.827s 10 1.32x
🐘 Postgres Nitro 0.194s (+16.8% 🔺) 0.994s (~) 0.001s (-20.0% 🟢) 1.012s (~) 0.818s 10 1.39x
🌐 MongoDB Next.js (Turbopack) 0.508s (+7.1% 🔺) 0.936s (-3.5%) 0.002s (+28.6% 🔺) 1.009s (~) 0.501s 10 3.63x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 1.556s (+3.4%) 2.470s (+6.6% 🔺) 0.005s (-14.8% 🟢) 3.011s (+8.8% 🔺) 1.455s 10 1.00x
▲ Vercel Express 1.639s (+8.8% 🔺) 2.340s (+7.8% 🔺) 0.006s (+30.2% 🔺) 2.918s (+5.4% 🔺) 1.279s 10 1.05x
▲ Vercel Next.js (Turbopack) 1.660s (+7.7% 🔺) 2.712s (+22.7% 🔺) 0.005s (+4.0%) 3.268s (+17.8% 🔺) 1.608s 10 1.07x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Next.js (Turbopack) 6/12
🐘 Postgres Nitro 4/12
▲ Vercel Express 7/12
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 6/12
Next.js (Turbopack) 🌐 Redis 8/12
Nitro 🐘 Postgres 6/12
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)

📋 View full workflow run

@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: dfdf60a

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

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

};

// Check for duplicate token before creating hook
const hooksDir = path.join(basedir, 'hooks');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Only minor concern is that if an existing workspace(from before this version) has hook files, a duplicate token can be created once because the constraint file is missing?

Copy link
Member Author

Choose a reason for hiding this comment

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

We limit backwards compat in world-local to only ensure old runs can continue running, and can be viewed in o11y, so I think this is fine

Copy link
Collaborator

@karthikscale3 karthikscale3 left a comment

Choose a reason for hiding this comment

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

just left one comment, otherwise looks good to me.

Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
@VaguelySerious VaguelySerious merged commit 9feebee into main Mar 12, 2026
103 of 105 checks passed
@VaguelySerious VaguelySerious deleted the peter/local-storage-hook-race branch March 12, 2026 18:56
pranaygp added a commit that referenced this pull request Mar 13, 2026
…ignal

* origin/main:
  fix: separate infrastructure vs user code error handling (#1339)
  Revert "Fix e2e CLI SIGTERM flake: use SIGKILL to reliably kill hung processes"
  Fix e2e CLI SIGTERM flake: use SIGKILL to reliably kill hung processes
  ci: fix git identity for changesets Version Packages commit (#1357)
  ci: configure git identity for GitHub App bot account (#1356)
  fix(cli): remove short flag collision on `-e` in health command (#1343)
  Fix flaky Vercel prod e2e tests by skipping CLI update check (#1350)
  Fix Windows `ERR_UNSUPPORTED_ESM_URL_SCHEME` in dynamic imports (#1346)
  Fix flaky hook test by replacing setTimeout with deterministic awaits (#1347)
  ci: use dedicated GitHub App token instead of shared PAT (#1351)
  [world-local] Enforce hook token uniqueness and atomicity, matches other worlds (#1348)
  fix(core): suppress stale WORKFLOW_VERCEL_* env var warning outside serverless runtime (#1345)

# Conflicts:
#	packages/core/src/runtime/step-handler.ts
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.

2 participants