Skip to content

fix(builders) - support explicit project roots in swc transforms#1399

Merged
AndrewBarba merged 8 commits intomainfrom
barba/codex/builder-explicit-project-root
Mar 20, 2026
Merged

fix(builders) - support explicit project roots in swc transforms#1399
AndrewBarba merged 8 commits intomainfrom
barba/codex/builder-explicit-project-root

Conversation

@AndrewBarba
Copy link
Contributor

@AndrewBarba AndrewBarba commented Mar 16, 2026

Summary

  • add an optional projectRoot to builder config so SWC/module-specifier resolution does not have to rely on global cwd
  • thread that root through discovery, SWC transforms, and the Next deferred builder while preserving existing defaults
  • add focused builders tests that prove workspace package ids can be resolved from a consuming app root

Why

[secret framework] currently has to temporarily mutate process.cwd() when invoking Workflow builders so package-owned workflows resolve to stable package ids from the app root. This change makes that root explicit and keeps the current behavior as the fallback when projectRoot is omitted.

Validation

  • pnpm exec vitest run packages/builders/src/module-specifier.test.ts packages/builders/src/swc-esbuild-plugin.test.ts packages/builders/src/discover-entries-esbuild-plugin.test.ts
  • pnpm --filter @workflow/builders typecheck
  • pnpm --filter @workflow/builders build
  • pnpm --filter @workflow/next build

@AndrewBarba AndrewBarba requested review from a team and ijjk as code owners March 16, 2026 16:49
@changeset-bot
Copy link

changeset-bot bot commented Mar 16, 2026

⚠️ No Changeset found

Latest commit: 961ab1b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel
Copy link
Contributor

vercel bot commented Mar 16, 2026

@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 2026

🧪 E2E Test Results

Some tests failed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 758 0 67 825
✅ 💻 Local Development 782 0 118 900
✅ 📦 Local Production 782 0 118 900
✅ 🐘 Local Postgres 782 0 118 900
✅ 🪟 Windows 72 0 3 75
❌ 🌍 Community Worlds 118 56 15 189
✅ 📋 Other 198 0 27 225
Total 3492 56 466 4014

❌ Failed Tests

🌍 Community Worlds (56 failed)

mongodb (3 failed):

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

redis (2 failed):

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

turso (51 failed):

  • addTenWorkflow | wrun_01KM4BYFW57CFEW8GR7058Y8YK
  • addTenWorkflow | wrun_01KM4BYFW57CFEW8GR7058Y8YK
  • wellKnownAgentWorkflow (.well-known/agent) | wrun_01KM4C04F6ST94SKYNP17MMNX8
  • should work with react rendering in step
  • promiseAllWorkflow | wrun_01KM4BYQV4WVMGFYHWWT2N8775
  • promiseRaceWorkflow | wrun_01KM4BYWDG2SYBMSKTTY2HQDSF
  • promiseAnyWorkflow | wrun_01KM4BYYJQMAHQ5KKR1V30PRVG
  • importedStepOnlyWorkflow | wrun_01KM4C0FKZ7W7WN5RB075XY6JC
  • hookWorkflow | wrun_01KM4BZDJAN8AYF7HC72YV5VS8
  • hookWorkflow is not resumable via public webhook endpoint | wrun_01KM4BZSJE52H0EYCFZZY4VSW7
  • webhookWorkflow | wrun_01KM4C01227QX4JVHQ83V2VZ11
  • sleepingWorkflow | wrun_01KM4C07GVPPA96WB4HYJP7Y1N
  • parallelSleepWorkflow | wrun_01KM4C0MFK08DYN8HMEQ14KVZJ
  • nullByteWorkflow | wrun_01KM4C0RZCQV4VHYWPS3JM4JMB
  • workflowAndStepMetadataWorkflow | wrun_01KM4C0V3R905B3DPK2TAFCNJ6
  • fetchWorkflow | wrun_01KM4C1QESMNQJT4XF9ZT4J99N
  • promiseRaceStressTestWorkflow | wrun_01KM4C1VRTVGTTEDTGNFKR0NMR
  • 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 catchability FatalError can be caught and detected with FatalError.is()
  • hookCleanupTestWorkflow - hook token reuse after workflow completion | wrun_01KM4C4V60Q99Q74P2C2PCTD9X
  • concurrent hook token conflict - two workflows cannot use the same hook token simultaneously | wrun_01KM4C5ED7K640GEK1RQBFBJ28
  • hookDisposeTestWorkflow - hook token reuse after explicit disposal while workflow still running | wrun_01KM4C63C2PF4JAQKHFAZQBXRZ
  • stepFunctionPassingWorkflow - step function references can be passed as arguments (without closure vars) | wrun_01KM4C6Q3HVWYHN7H3497D2C4X
  • stepFunctionWithClosureWorkflow - step function with closure variables passed as argument | wrun_01KM4C70AGVE6R6X3SNPH40D42
  • closureVariableWorkflow - nested step functions with closure variables | wrun_01KM4C76A3094QBQGFHV77WYS8
  • spawnWorkflowFromStepWorkflow - spawning a child workflow using start() inside a step | wrun_01KM4C7BD1D977NJE4PSEFDP43
  • health check (queue-based) - workflow and step endpoints respond to health check messages
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_01KM4C7V3M58YZ7MP8FGJ31CCR
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_01KM4C81K6VPBVTEFGEZPKFEGQ
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_01KM4C889A40D6KRP6JCT2Z14E
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_01KM4C8DRVYK5WNHNGEE2X2TWP
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_01KM4C8MK3QFY10ANYFB4Z7ZW0
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_01KM4C8VD64VV24JNMMEY9N4GG
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_01KM4C92426F8TS05TVFV82XY8
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_01KM4C9DARF3DDFVP0APB8WM7E
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_01KM4C9N80CT63JQ0CP78A1H1N
  • cancelRun - cancelling a running workflow | wrun_01KM4C9VYJHV9CYHQ36FVYSZEZ
  • cancelRun via CLI - cancelling a running workflow | wrun_01KM4CA5VHG5J92ZSBR8MHTDDC
  • 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 | wrun_01KM4CAKF5TGW3Z18CJ4VQ1E8R
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration | wrun_01KM4CB8ABW93GQZ5K05SV41AV
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_01KM4CBJ38FRE0EWA1MQK8E3PY

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 68 0 7
✅ example 68 0 7
✅ express 68 0 7
✅ fastify 68 0 7
✅ hono 68 0 7
✅ nextjs-turbopack 73 0 2
✅ nextjs-webpack 73 0 2
✅ nitro 68 0 7
✅ nuxt 68 0 7
✅ sveltekit 68 0 7
✅ vite 68 0 7
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 66 0 9
✅ express-stable 66 0 9
✅ fastify-stable 66 0 9
✅ hono-stable 66 0 9
✅ nextjs-turbopack-canary 55 0 20
✅ nextjs-turbopack-stable 72 0 3
✅ nextjs-webpack-canary 55 0 20
✅ nextjs-webpack-stable 72 0 3
✅ nitro-stable 66 0 9
✅ nuxt-stable 66 0 9
✅ sveltekit-stable 66 0 9
✅ vite-stable 66 0 9
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 66 0 9
✅ express-stable 66 0 9
✅ fastify-stable 66 0 9
✅ hono-stable 66 0 9
✅ nextjs-turbopack-canary 55 0 20
✅ nextjs-turbopack-stable 72 0 3
✅ nextjs-webpack-canary 55 0 20
✅ nextjs-webpack-stable 72 0 3
✅ nitro-stable 66 0 9
✅ nuxt-stable 66 0 9
✅ sveltekit-stable 66 0 9
✅ vite-stable 66 0 9
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 66 0 9
✅ express-stable 66 0 9
✅ fastify-stable 66 0 9
✅ hono-stable 66 0 9
✅ nextjs-turbopack-canary 55 0 20
✅ nextjs-turbopack-stable 72 0 3
✅ nextjs-webpack-canary 55 0 20
✅ nextjs-webpack-stable 72 0 3
✅ nitro-stable 66 0 9
✅ nuxt-stable 66 0 9
✅ sveltekit-stable 66 0 9
✅ vite-stable 66 0 9
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 72 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 66 0 9
✅ e2e-local-postgres-nest-stable 66 0 9
✅ e2e-local-prod-nest-stable 66 0 9

📋 View full workflow run

@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 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.042s (-13.5% 🟢) 1.006s (~) 0.964s 10 1.00x
💻 Local Nitro 0.043s (+11.9% 🔺) 1.005s (~) 0.962s 10 1.04x
💻 Local Next.js (Turbopack) 0.049s 1.005s 0.957s 10 1.17x
🌐 Redis Next.js (Turbopack) 0.054s 1.005s 0.952s 10 1.29x
🐘 Postgres Express 0.061s (-23.8% 🟢) 1.012s (~) 0.951s 10 1.47x
🐘 Postgres Next.js (Turbopack) 0.061s 1.011s 0.950s 10 1.47x
🐘 Postgres Nitro 0.066s (-4.8%) 1.014s (-0.6%) 0.948s 10 1.59x
🌐 MongoDB Next.js (Turbopack) 0.101s 1.008s 0.907s 10 2.44x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 0.450s (-13.3% 🟢) 2.188s (-9.8% 🟢) 1.737s 10 1.00x
▲ Vercel Nitro 0.472s (-8.7% 🟢) 2.318s (-5.9% 🟢) 1.846s 10 1.05x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Next.js (Turbopack) 1.121s 2.006s 0.885s 10 1.00x
🌐 Redis Next.js (Turbopack) 1.124s 2.007s 0.883s 10 1.00x
💻 Local Nitro 1.125s (+3.0%) 2.006s (~) 0.881s 10 1.00x
💻 Local Express 1.130s (~) 2.005s (~) 0.875s 10 1.01x
🐘 Postgres Next.js (Turbopack) 1.139s 2.012s 0.873s 10 1.02x
🐘 Postgres Express 1.148s (~) 2.013s (~) 0.865s 10 1.02x
🐘 Postgres Nitro 1.155s (+0.6%) 2.013s (~) 0.858s 10 1.03x
🌐 MongoDB Next.js (Turbopack) 1.314s 2.008s 0.694s 10 1.17x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.018s (-0.9%) 3.445s (-5.9% 🟢) 1.427s 10 1.00x
▲ Vercel Nitro 2.103s (-4.5%) 3.464s (-9.5% 🟢) 1.360s 10 1.04x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 10.750s 11.023s 0.273s 3 1.00x
💻 Local Next.js (Turbopack) 10.836s 11.023s 0.187s 3 1.01x
💻 Local Express 10.904s (-0.7%) 11.022s (~) 0.118s 3 1.01x
💻 Local Nitro 10.908s (+2.7%) 11.023s (~) 0.115s 3 1.01x
🐘 Postgres Next.js (Turbopack) 10.913s 11.041s 0.129s 3 1.02x
🐘 Postgres Express 10.952s (+0.7%) 11.047s (~) 0.094s 3 1.02x
🐘 Postgres Nitro 11.005s (~) 11.051s (-5.7% 🟢) 0.046s 3 1.02x
🌐 MongoDB Next.js (Turbopack) 12.273s 13.025s 0.752s 3 1.14x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 16.881s (~) 18.363s (-1.9%) 1.482s 2 1.00x
▲ Vercel Express 17.508s (+4.9%) 18.612s (+1.7%) 1.104s 2 1.04x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 14.241s 15.029s 0.788s 4 1.00x
🐘 Postgres Next.js (Turbopack) 14.514s 15.040s 0.526s 4 1.02x
💻 Local Next.js (Turbopack) 14.591s 15.029s 0.438s 4 1.02x
🐘 Postgres Express 14.761s (-45.6% 🟢) 15.048s (-46.4% 🟢) 0.287s 4 1.04x
🐘 Postgres Nitro 14.835s (-45.6% 🟢) 15.047s (-46.4% 🟢) 0.212s 4 1.04x
💻 Local Express 14.914s (-46.0% 🟢) 15.029s (-46.4% 🟢) 0.115s 4 1.05x
💻 Local Nitro 14.936s (-44.2% 🟢) 15.028s (-44.4% 🟢) 0.091s 4 1.05x
🌐 MongoDB Next.js (Turbopack) 17.794s 18.023s 0.229s 4 1.25x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 32.236s (-28.2% 🟢) 33.737s (-28.2% 🟢) 1.500s 2 1.00x
▲ Vercel Express 32.352s (-28.7% 🟢) 33.700s (-27.7% 🟢) 1.348s 2 1.00x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 13.407s 14.026s 0.619s 7 1.00x
🐘 Postgres Next.js (Turbopack) 14.020s 14.752s 0.732s 7 1.05x
🐘 Postgres Express 14.261s (-73.7% 🟢) 15.043s (-72.7% 🟢) 0.782s 6 1.06x
🐘 Postgres Nitro 14.511s (-73.4% 🟢) 15.041s (-72.7% 🟢) 0.531s 6 1.08x
💻 Local Next.js (Turbopack) 15.856s 16.195s 0.340s 6 1.18x
💻 Local Express 16.361s (-71.1% 🟢) 17.028s (-70.2% 🟢) 0.667s 6 1.22x
💻 Local Nitro 16.518s (-69.9% 🟢) 17.030s (-69.1% 🟢) 0.512s 6 1.23x
🌐 MongoDB Next.js (Turbopack) 20.338s 21.024s 0.686s 5 1.52x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 55.697s (-45.2% 🟢) 57.320s (-44.5% 🟢) 1.623s 2 1.00x
▲ Vercel Express 57.419s (-39.9% 🟢) 59.481s (-38.8% 🟢) 2.062s 2 1.03x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Next.js (Turbopack) 1.262s 2.010s 0.748s 15 1.00x
🐘 Postgres Nitro 1.270s (-1.8%) 2.011s (~) 0.741s 15 1.01x
🐘 Postgres Express 1.277s (~) 2.012s (~) 0.735s 15 1.01x
🌐 Redis Next.js (Turbopack) 1.350s 2.007s 0.657s 15 1.07x
💻 Local Nitro 1.486s (+0.7%) 2.005s (~) 0.519s 15 1.18x
💻 Local Express 1.487s (-2.4%) 2.006s (~) 0.519s 15 1.18x
💻 Local Next.js (Turbopack) 1.505s 2.005s 0.500s 15 1.19x
🌐 MongoDB Next.js (Turbopack) 2.162s 3.008s 0.846s 10 1.71x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.392s (-3.6%) 3.621s (-7.0% 🟢) 1.228s 9 1.00x
▲ Vercel Express 2.461s (+6.1% 🔺) 3.686s (-2.3%) 1.226s 9 1.03x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Next.js (Turbopack) 2.428s 3.012s 0.584s 10 1.00x
🐘 Postgres Nitro 2.435s (-1.3%) 3.011s (~) 0.576s 10 1.00x
🐘 Postgres Express 2.464s (~) 3.013s (~) 0.548s 10 1.02x
🌐 Redis Next.js (Turbopack) 2.541s 3.008s 0.467s 10 1.05x
💻 Local Next.js (Turbopack) 2.715s 3.007s 0.292s 10 1.12x
💻 Local Express 2.926s (-3.9%) 3.207s (-7.1% 🟢) 0.281s 10 1.21x
💻 Local Nitro 2.961s (+15.4% 🔺) 3.341s (+11.1% 🔺) 0.380s 9 1.22x
🌐 MongoDB Next.js (Turbopack) 4.648s 5.177s 0.529s 6 1.91x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.512s (-7.7% 🟢) 3.942s (-3.5%) 1.430s 8 1.00x
▲ Vercel Express 3.067s (+8.6% 🔺) 4.476s (+2.6%) 1.409s 7 1.22x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 3.568s (-0.9%) 4.013s (~) 0.446s 8 1.00x
🐘 Postgres Express 3.639s (+1.7%) 4.014s (~) 0.375s 8 1.02x
🐘 Postgres Next.js (Turbopack) 3.730s 4.013s 0.283s 8 1.05x
🌐 Redis Next.js (Turbopack) 4.163s 4.869s 0.705s 7 1.17x
💻 Local Next.js (Turbopack) 7.579s 8.267s 0.688s 4 2.12x
💻 Local Express 8.222s (-3.8%) 9.021s (-2.7%) 0.799s 4 2.30x
💻 Local Nitro 8.792s (+15.9% 🔺) 9.276s (+12.2% 🔺) 0.484s 4 2.46x
🌐 MongoDB Next.js (Turbopack) 9.756s 10.351s 0.595s 3 2.73x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.097s (~) 4.100s (-5.1% 🟢) 1.003s 8 1.00x
▲ Vercel Express 3.102s (+11.5% 🔺) 4.207s (-2.8%) 1.106s 8 1.00x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Next.js (Turbopack) 1.253s 2.010s 0.757s 15 1.00x
🐘 Postgres Express 1.270s (+0.6%) 2.011s (~) 0.741s 15 1.01x
🐘 Postgres Nitro 1.273s (-1.0%) 2.011s (~) 0.739s 15 1.02x
🌐 Redis Next.js (Turbopack) 1.285s 2.006s 0.721s 15 1.03x
💻 Local Nitro 1.512s (+1.2%) 2.005s (~) 0.493s 15 1.21x
💻 Local Express 1.541s (-1.0%) 2.006s (~) 0.465s 15 1.23x
💻 Local Next.js (Turbopack) 1.545s 2.006s 0.461s 15 1.23x
🌐 MongoDB Next.js (Turbopack) 2.196s 3.007s 0.811s 10 1.75x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.152s (-34.5% 🟢) 3.394s (-28.0% 🟢) 1.242s 9 1.00x
▲ Vercel Nitro 2.264s (-1.9%) 3.678s (-2.3%) 1.413s 9 1.05x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 2.447s (-1.2%) 3.012s (~) 0.565s 10 1.00x
🐘 Postgres Express 2.449s (~) 3.013s (~) 0.563s 10 1.00x
🐘 Postgres Next.js (Turbopack) 2.462s 3.011s 0.549s 10 1.01x
🌐 Redis Next.js (Turbopack) 2.580s 3.008s 0.428s 10 1.05x
💻 Local Next.js (Turbopack) 2.870s 3.565s 0.695s 9 1.17x
💻 Local Nitro 3.007s (+13.7% 🔺) 3.676s (+22.2% 🔺) 0.669s 9 1.23x
💻 Local Express 3.304s (~) 4.009s (-3.1%) 0.705s 8 1.35x
🌐 MongoDB Next.js (Turbopack) 4.661s 5.177s 0.516s 6 1.90x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.360s (-11.7% 🟢) 3.402s (-14.9% 🟢) 1.042s 10 1.00x
▲ Vercel Nitro 2.805s (+7.1% 🔺) 4.351s (+7.1% 🔺) 1.546s 8 1.19x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 3.611s (~) 4.014s (~) 0.403s 8 1.00x
🐘 Postgres Express 3.676s (+1.9%) 4.142s (+3.1%) 0.466s 8 1.02x
🐘 Postgres Next.js (Turbopack) 3.741s 4.014s 0.273s 8 1.04x
🌐 Redis Next.js (Turbopack) 4.183s 5.012s 0.829s 6 1.16x
💻 Local Express 8.411s (-5.3% 🟢) 9.021s (-2.7%) 0.610s 4 2.33x
💻 Local Nitro 8.488s (+10.4% 🔺) 9.022s (+12.5% 🔺) 0.534s 4 2.35x
💻 Local Next.js (Turbopack) 8.545s 9.018s 0.472s 4 2.37x
🌐 MongoDB Next.js (Turbopack) 9.994s 10.349s 0.354s 3 2.77x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.713s (-13.9% 🟢) 4.152s (-13.9% 🟢) 1.438s 8 1.00x
▲ Vercel Nitro 2.853s (-1.8%) 4.442s (+5.9% 🔺) 1.589s 7 1.05x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 0.699s 1.005s 0.305s 60 1.00x
🐘 Postgres Next.js (Turbopack) 0.802s 1.026s 0.224s 59 1.15x
💻 Local Next.js (Turbopack) 0.852s 1.039s 0.187s 58 1.22x
🐘 Postgres Nitro 0.869s 1.025s 0.157s 59 1.24x
🐘 Postgres Express 0.891s 1.026s 0.135s 59 1.27x
💻 Local Express 0.962s 1.021s 0.059s 59 1.38x
💻 Local Nitro 0.965s 1.039s 0.074s 58 1.38x
🌐 MongoDB Next.js (Turbopack) 2.146s 3.008s 0.862s 20 3.07x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 9.433s 11.042s 1.610s 6 1.00x
▲ Vercel Express 9.806s 11.186s 1.379s 6 1.04x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 1.712s 2.028s 0.316s 45 1.00x
🐘 Postgres Next.js (Turbopack) 1.969s 2.177s 0.207s 42 1.15x
🐘 Postgres Nitro 2.094s 2.947s 0.853s 31 1.22x
🐘 Postgres Express 2.192s 3.012s 0.820s 30 1.28x
💻 Local Next.js (Turbopack) 2.595s 3.007s 0.412s 30 1.52x
💻 Local Express 2.951s 3.108s 0.157s 30 1.72x
💻 Local Nitro 2.981s 3.378s 0.397s 27 1.74x
🌐 MongoDB Next.js (Turbopack) 5.230s 6.011s 0.782s 15 3.05x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 30.761s 32.504s 1.742s 3 1.00x
▲ Vercel Express 31.035s 31.966s 0.932s 3 1.01x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 3.399s 4.009s 0.610s 30 1.00x
🐘 Postgres Next.js (Turbopack) 4.028s 4.496s 0.468s 27 1.19x
🐘 Postgres Nitro 4.349s 5.014s 0.666s 24 1.28x
🐘 Postgres Express 4.412s 5.014s 0.602s 24 1.30x
💻 Local Next.js (Turbopack) 8.389s 9.017s 0.628s 14 2.47x
💻 Local Express 8.955s 9.478s 0.524s 13 2.63x
💻 Local Nitro 9.038s 9.556s 0.518s 13 2.66x
🌐 MongoDB Next.js (Turbopack) 10.635s 11.017s 0.382s 11 3.13x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 80.619s 82.195s 1.576s 2 1.00x
▲ Vercel Express 82.249s 83.732s 1.483s 2 1.02x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Next.js (Turbopack) 0.282s 1.009s 0.727s 60 1.00x
🐘 Postgres Nitro 0.293s 1.009s 0.716s 60 1.04x
🐘 Postgres Express 0.295s 1.009s 0.714s 60 1.05x
🌐 Redis Next.js (Turbopack) 0.402s 1.004s 0.602s 60 1.43x
💻 Local Next.js (Turbopack) 0.544s 1.004s 0.460s 60 1.93x
💻 Local Nitro 0.575s 1.004s 0.429s 60 2.04x
💻 Local Express 0.584s 1.004s 0.421s 60 2.07x
🌐 MongoDB Next.js (Turbopack) 1.649s 2.149s 0.500s 28 5.85x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.748s 3.074s 1.326s 20 1.00x
▲ Vercel Nitro 1.919s 3.245s 1.326s 19 1.10x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.532s 1.009s 0.478s 90 1.00x
🐘 Postgres Nitro 0.532s 1.009s 0.478s 90 1.00x
🐘 Postgres Next.js (Turbopack) 0.544s 1.009s 0.466s 90 1.02x
🌐 Redis Next.js (Turbopack) 1.192s 2.006s 0.814s 45 2.24x
💻 Local Express 2.464s 3.009s 0.545s 30 4.64x
💻 Local Nitro 2.482s 3.009s 0.527s 30 4.67x
💻 Local Next.js (Turbopack) 2.487s 3.008s 0.522s 30 4.68x
🌐 MongoDB Next.js (Turbopack) 4.759s 5.305s 0.545s 17 8.95x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.660s 5.000s 1.340s 19 1.00x
▲ Vercel Nitro 3.745s 5.003s 1.258s 19 1.02x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.899s 1.115s 0.217s 108 1.00x
🐘 Postgres Next.js (Turbopack) 0.921s 1.146s 0.225s 105 1.02x
🐘 Postgres Express 0.934s 1.193s 0.259s 101 1.04x
🌐 Redis Next.js (Turbopack) 2.681s 3.007s 0.326s 40 2.98x
🌐 MongoDB Next.js (Turbopack) 9.912s 10.517s 0.605s 12 11.03x
💻 Local Next.js (Turbopack) 10.447s 10.934s 0.488s 11 11.63x
💻 Local Express 10.953s 11.480s 0.527s 11 12.19x
💻 Local Nitro 11.011s 11.754s 0.743s 11 12.25x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 8.078s 9.296s 1.218s 13 1.00x
▲ Vercel Nitro 8.336s 9.648s 1.312s 13 1.03x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - -

🔍 Observability: Express | Nitro

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.173s 1.002s 0.011s 1.017s 0.844s 10 1.00x
🌐 Redis Next.js (Turbopack) 0.178s 0.999s 0.002s 1.007s 0.829s 10 1.03x
💻 Local Nitro 0.198s (+43.4% 🔺) 1.003s (~) 0.011s (+17.9% 🔺) 1.017s (~) 0.819s 10 1.14x
💻 Local Express 0.201s (-1.2%) 1.003s (~) 0.011s (-4.3%) 1.017s (~) 0.816s 10 1.16x
🐘 Postgres Next.js (Turbopack) 0.208s 1.001s 0.002s 1.013s 0.806s 10 1.20x
🐘 Postgres Nitro 0.226s (-3.6%) 1.000s (~) 0.001s (~) 1.013s (~) 0.787s 10 1.31x
🐘 Postgres Express 0.227s (+11.1% 🔺) 0.992s (-0.5%) 0.001s (-42.1% 🟢) 1.012s (~) 0.785s 10 1.31x
🌐 MongoDB Next.js (Turbopack) 0.532s 0.928s 0.002s 1.009s 0.477s 10 3.08x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.616s (+2.1%) 2.478s (+0.6%) 0.004s (-31.0% 🟢) 3.121s (+3.2%) 1.505s 10 1.00x
▲ Vercel Nitro 1.749s (+4.7%) 3.049s (+25.9% 🔺) 0.006s (-98.5% 🟢) 3.518s (+2.8%) 1.769s 10 1.08x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - - -

🔍 Observability: Express | Nitro

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 0.551s 1.001s 0.003s 1.012s 0.461s 60 1.00x
💻 Local Next.js (Turbopack) 0.655s 1.008s 0.010s 1.024s 0.369s 59 1.19x
🐘 Postgres Next.js (Turbopack) 0.722s 1.009s 0.004s 1.027s 0.305s 59 1.31x
💻 Local Express 0.725s 1.009s 0.010s 1.023s 0.298s 59 1.32x
🐘 Postgres Express 0.728s 1.005s 0.004s 1.028s 0.300s 59 1.32x
💻 Local Nitro 0.729s 1.009s 0.008s 1.023s 0.294s 59 1.32x
🐘 Postgres Nitro 0.741s 1.022s 0.004s 1.047s 0.306s 59 1.35x
🌐 MongoDB Next.js (Turbopack) 1.316s 1.954s 0.003s 2.013s 0.697s 30 2.39x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 4.037s 5.004s 0.262s 5.830s 1.793s 11 1.00x
▲ Vercel Nitro 9.232s 10.863s 0.196s 11.592s 2.360s 6 2.29x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - - -

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 0.793s 1.017s 0.000s 1.021s 0.229s 59 1.00x
🐘 Postgres Express 0.901s 1.080s 0.000s 1.116s 0.216s 54 1.14x
🐘 Postgres Next.js (Turbopack) 0.924s 1.112s 0.000s 1.121s 0.197s 54 1.17x
🐘 Postgres Nitro 0.926s 1.146s 0.000s 1.164s 0.238s 52 1.17x
💻 Local Express 1.222s 2.018s 0.000s 2.021s 0.798s 30 1.54x
💻 Local Nitro 1.238s 2.020s 0.000s 2.023s 0.785s 30 1.56x
💻 Local Next.js (Turbopack) 1.248s 2.019s 0.000s 2.023s 0.775s 30 1.57x
🌐 MongoDB Next.js (Turbopack) 2.341s 2.949s 0.000s 3.008s 0.666s 20 2.95x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.431s 3.173s 0.001s 3.666s 1.235s 17 1.00x
▲ Vercel Express 2.775s 3.514s 0.000s 3.928s 1.152s 16 1.14x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - - -

🔍 Observability: Nitro | Express

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

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🌐 Redis 🥇 Next.js (Turbopack) 1.508s 2.001s 0.000s 2.006s 0.498s 30 1.00x
🐘 Postgres Express 1.881s 2.172s 0.000s 2.194s 0.313s 28 1.25x
🐘 Postgres Nitro 1.920s 2.168s 0.000s 2.185s 0.265s 29 1.27x
🐘 Postgres Next.js (Turbopack) 1.932s 2.188s 0.000s 2.225s 0.293s 27 1.28x
💻 Local Express 3.417s 4.032s 0.001s 4.036s 0.619s 15 2.27x
💻 Local Nitro 3.496s 4.101s 0.001s 4.105s 0.610s 15 2.32x
💻 Local Next.js (Turbopack) 3.576s 4.163s 0.001s 4.168s 0.592s 15 2.37x
🌐 MongoDB Next.js (Turbopack) 4.357s 4.952s 0.000s 5.009s 0.652s 12 2.89x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.165s 4.134s 0.000s 4.621s 1.456s 13 1.00x
▲ Vercel Express 3.325s 4.237s 0.000s 4.682s 1.357s 13 1.05x
▲ Vercel Next.js (Turbopack) ⚠️ missing - - - - -

🔍 Observability: Nitro | Express

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Next.js (Turbopack) 14/21
🐘 Postgres Next.js (Turbopack) 13/21
▲ Vercel Nitro 11/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 13/21
Next.js (Turbopack) 🌐 Redis 9/21
Nitro 🐘 Postgres 14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

Copy link
Collaborator

@pranaygp pranaygp left a comment

Choose a reason for hiding this comment

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

@ijjk left a comment for code reuse but otherwise looks good

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.

4 participants