Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
[core] Turbo: skip the unused run_started event-log preload by VaguelySerious · Pull Request #2569 · vercel/workflow · GitHub
Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [core] Turbo: skip the unused run_started event-log preload by VaguelySerious · Pull Request #2569 · vercel/workflow · GitHub
Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [core] Turbo: skip the unused run_started event-log preload by VaguelySerious · Pull Request #2569 · vercel/workflow · GitHub
Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' [core] Turbo: skip the unused run_started event-log preload by VaguelySerious · Pull Request #2569 · vercel/workflow · GitHub
Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [core] Turbo: skip the unused run_started event-log preload by VaguelySerious · Pull Request #2569 · vercel/workflow · GitHub
Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [core] Turbo: skip the unused run_started event-log preload by VaguelySerious · Pull Request #2569 · vercel/workflow · GitHub
Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); [core] Turbo: skip the unused run_started event-log preload by VaguelySerious · Pull Request #2569 · vercel/workflow · GitHub
Skip to content

[core] Turbo: skip the unused run_started event-log preload - #2569

Merged
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload
Jun 22, 2026
Merged

[core] Turbo: skip the unused run_started event-log preload#2569
VaguelySerious merged 2 commits into
mainfrom
peter/turbo-skip-run-started-preload

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Jun 22, 2026

Copy link
Copy Markdown
Member

Turbo backgrounds run_started purely as a write barrier and synthesizes the run locally (preloadedEvents is forced to []), so it never reads the event-log preload world-vercel returns on run_started. This adds a new advisory skipEventPreload on CreateEventParams; the turbo path sets it on the run_started create, and world-vercel forwards it as a skipPreload v4 frame-meta flag so the backend can skip the wasted list + resolve.

Why it matters

The first step_started is chained on the run_started barrier (step-executor.tsrunReadyBarrier.then(() => create(step_started))), so run_started's request duration sits directly in front of the first durable step_started, and step_completed is ordered after that. Trimming the preload shortens run_started, which advances the first step_started and therefore time-to-second-step.

Safety / compatibility

  • Honored only for run_started; ignored by Worlds that don't preload.
  • The runtime always falls back to events.list if it ever needs the log (e.g. on turbo exit), so omitting the preload never deprives it of data.
  • A redelivery (attempt > 1) is not turbo, awaits run_started, and consumes the preload — so it does not send the flag.
  • Additive wire field: old servers ignore it; works in any deploy order.

Turbo backgrounds run_started purely as a write barrier and synthesizes the
run locally (preloadedEvents is forced to []), so it never reads the event-log
preload the World returns on run_started. It now passes a new advisory
`skipEventPreload` on that create; world-vercel forwards it as a `skipPreload`
frame-meta flag so the backend can skip the wasted list+resolve.
Because the first step_started is chained on the run_started barrier, trimming
the run_started request directly shortens the wait before the first durable
step_started — i.e. time-to-second-step. The flag is honored only for
run_started and ignored by Worlds that don't preload; the runtime always falls
back to events.list if it ever needs the log, so it is fully backward
compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7a2b22

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

This PR includes changesets to release 20 packages
NameType
@workflow/corePatch
@workflow/worldPatch
@workflow/world-vercelPatch
@workflow/buildersPatch
@workflow/cliPatch
@workflow/nextPatch
@workflow/nitroPatch
@workflow/vitestPatch
@workflow/web-sharedPatch
@workflow/webPatch
workflowPatch
@workflow/world-testingPatch
@workflow/world-localPatch
@workflow/world-postgresPatch
@workflow/astroPatch
@workflow/nestPatch
@workflow/rollupPatch
@workflow/sveltekitPatch
@workflow/vitePatch
@workflow/nuxtPatch

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

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express0.047s (+14.6% 🔺)1.006s (~)0.959s101.00x
💻 LocalNitro0.048s (+18.0% 🔺)1.006s (~)0.958s101.03x
💻 LocalNext.js (Turbopack)0.049s (+2.5%)1.006s (~)0.956s101.04x
🐘 PostgresNext.js (Turbopack)0.061s (+4.5%)1.014s (~)0.953s101.28x
🐘 PostgresNitro0.062s (-2.2%)1.012s (~)0.951s101.31x
🐘 PostgresExpress0.068s (+10.0% 🔺)1.012s (~)0.944s101.44x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.283s (-28.8% 🟢)2.377s (-2.5%)2.094s101.00x
▲ VercelNitro0.430s (+10.2% 🔺)2.373s (-6.1% 🟢)1.943s101.52x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express1.081s (-1.7%)2.006s (~)0.925s101.00x
💻 LocalNext.js (Turbopack)1.083s (-0.8%)2.007s (~)0.924s101.00x
💻 LocalNitro1.084s (~)2.006s (~)0.922s101.00x
🐘 PostgresNitro1.093s (-0.9%)2.010s (~)0.917s101.01x
🐘 PostgresNext.js (Turbopack)1.098s (~)2.010s (~)0.912s101.02x
🐘 PostgresExpress1.099s (~)2.010s (~)0.911s101.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.479s (-4.0%)3.532s (+0.6%)2.053s101.00x
▲ VercelExpress1.569s (+3.1%)3.429s (-3.9%)1.860s101.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express10.449s (-0.6%)11.022s (~)0.573s31.00x
💻 LocalNitro10.450s (-0.6%)11.022s (~)0.573s31.00x
🐘 PostgresNitro10.452s (-0.9%)11.021s (~)0.569s31.00x
💻 LocalNext.js (Turbopack)10.495s (-0.5%)11.023s (~)0.528s31.00x
🐘 PostgresExpress10.512s (~)11.015s (~)0.503s31.01x
🐘 PostgresNext.js (Turbopack)10.527s (~)11.018s (~)0.491s31.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro11.912s (-7.2% 🟢)13.992s (-8.3% 🟢)2.080s31.00x
▲ VercelExpress11.963s (-8.6% 🟢)13.085s (-14.0% 🟢)1.122s31.00x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)13.602s (-0.8%)14.028s (~)0.426s51.00x
💻 LocalNitro13.618s (~)14.027s (~)0.410s51.00x
🐘 PostgresExpress13.619s (-1.2%)14.017s (~)0.398s51.00x
💻 LocalExpress13.631s (-2.6%)14.028s (-1.4%)0.397s51.00x
🐘 PostgresNitro13.649s (-1.9%)14.020s (~)0.371s51.00x
🐘 PostgresNext.js (Turbopack)13.865s (~)14.023s (~)0.158s51.02x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.959s (-10.9% 🟢)19.570s (-12.7% 🟢)1.610s41.00x
▲ VercelNitro19.041s (-11.4% 🟢)21.184s (-9.8% 🟢)2.143s41.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Express12.121s (-3.7%)13.026s (~)0.905s71.00x
💻 LocalNitro12.137s (-1.3%)13.025s (~)0.888s71.00x
🐘 PostgresNitro12.161s (-2.0%)13.020s (~)0.859s71.00x
💻 LocalNext.js (Turbopack)12.279s (-1.4%)13.024s (~)0.745s71.01x
🐘 PostgresExpress12.418s (~)13.017s (~)0.599s71.02x
🐘 PostgresNext.js (Turbopack)12.632s (+0.8%)13.162s (+1.1%)0.530s71.04x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express21.804s (-5.3% 🟢)23.889s (-5.0% 🟢)2.085s41.00x
▲ VercelNitro21.982s (-11.1% 🟢)24.373s (-8.7% 🟢)2.391s41.01x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.178s (-1.4%)2.008s (~)0.829s151.00x
🐘 PostgresNext.js (Turbopack)1.197s (+3.4%)2.008s (~)0.811s151.02x
🐘 PostgresNitro1.206s (+1.5%)2.008s (~)0.802s151.02x
💻 LocalExpress1.416s (+15.0% 🔺)2.007s (~)0.591s151.20x
💻 LocalNitro1.434s (+19.3% 🔺)2.006s (~)0.572s151.22x
💻 LocalNext.js (Turbopack)1.460s (+6.2% 🔺)2.007s (~)0.547s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.825s (+6.7% 🔺)4.436s (~)1.610s71.00x
▲ VercelExpress2.888s (+7.2% 🔺)4.521s (+1.4%)1.633s71.02x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)1.309s (+4.6%)3.010s (+50.0% 🔺)1.701s101.00x
🐘 PostgresNitro1.317s (+3.8%)2.316s (+15.4% 🔺)0.999s131.01x
🐘 PostgresExpress1.347s (+2.9%)2.293s (+10.5% 🔺)0.947s141.03x
💻 LocalNitro2.252s (+11.8% 🔺)2.735s (+9.1% 🔺)0.483s111.72x
💻 LocalExpress2.509s (+23.3% 🔺)2.918s (+16.4% 🔺)0.409s111.92x
💻 LocalNext.js (Turbopack)2.625s (+12.0% 🔺)3.344s (+14.6% 🔺)0.719s92.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.848s (~)4.575s (~)1.727s71.00x
▲ VercelNitro2.922s (+17.5% 🔺)4.700s (+15.8% 🔺)1.778s71.03x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.605s (-3.2%)4.441s (+18.0% 🔺)2.836s71.00x
🐘 PostgresNitro1.676s (+15.6% 🔺)4.137s (+12.4% 🔺)2.461s81.04x
🐘 PostgresNext.js (Turbopack)3.175s (+114.3% 🔺)5.851s (+50.6% 🔺)2.676s61.98x
💻 LocalNext.js (Turbopack)5.686s (-15.0% 🟢)6.217s (-16.2% 🟢)0.532s53.54x
💻 LocalNitro5.964s (+33.1% 🔺)6.616s (+32.0% 🔺)0.652s53.72x
💻 LocalExpress6.721s (+16.4% 🔺)7.418s (+15.7% 🔺)0.697s54.19x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.543s (+15.3% 🔺)5.574s (+13.0% 🔺)2.031s61.00x
▲ VercelNitro3.800s (+23.7% 🔺)5.931s (+20.7% 🔺)2.130s61.07x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.177s (-1.9%)2.007s (~)0.831s151.00x
🐘 PostgresExpress1.196s (~)2.006s (~)0.810s151.02x
🐘 PostgresNext.js (Turbopack)1.208s (+2.9%)2.009s (~)0.801s151.03x
💻 LocalExpress1.416s (+15.2% 🔺)2.007s (~)0.590s151.20x
💻 LocalNitro1.423s (+15.8% 🔺)2.006s (~)0.583s151.21x
💻 LocalNext.js (Turbopack)1.464s (+8.4% 🔺)2.007s (~)0.543s151.24x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.393s (+18.2% 🔺)4.271s (+9.4% 🔺)1.878s81.00x
▲ VercelNitro2.707s (+24.9% 🔺)4.455s (+14.9% 🔺)1.749s81.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.282s (+0.5%)2.592s (+29.1% 🔺)1.309s121.00x
🐘 PostgresExpress1.290s (~)2.393s (+19.2% 🔺)1.103s131.01x
🐘 PostgresNext.js (Turbopack)1.323s (+4.6%)3.009s (+45.0% 🔺)1.687s101.03x
💻 LocalNext.js (Turbopack)2.547s (+5.3% 🔺)3.109s (+6.6% 🔺)0.562s101.99x
💻 LocalNitro2.617s (+30.2% 🔺)3.344s (+44.5% 🔺)0.727s92.04x
💻 LocalExpress2.736s (+34.3% 🔺)3.009s (+10.0% 🔺)0.273s102.13x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.797s (+38.5% 🔺)5.552s (+29.2% 🔺)1.754s61.00x
▲ VercelExpress4.212s (+63.1% 🔺)6.116s (+40.7% 🔺)1.905s51.11x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.560s (+7.1% 🔺)4.009s (+6.6% 🔺)2.449s81.00x
🐘 PostgresExpress1.583s (+10.6% 🔺)4.011s (+6.7% 🔺)2.428s81.01x
🐘 PostgresNext.js (Turbopack)3.577s (+143.5% 🔺)6.417s (+65.2% 🔺)2.840s52.29x
💻 LocalNitro6.451s (+30.5% 🔺)6.817s (+23.6% 🔺)0.366s54.13x
💻 LocalExpress6.751s (+13.2% 🔺)7.217s (+5.9% 🔺)0.467s54.33x
💻 LocalNext.js (Turbopack)7.093s (+4.5%)7.617s (+1.4%)0.524s54.55x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.477s (+1.7%)6.185s (-5.9% 🟢)1.708s51.00x
▲ VercelExpress4.885s (+14.8% 🔺)6.850s (+12.4% 🔺)1.965s51.09x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.538s (-4.2%)1.023s (~)0.485s591.00x
🐘 PostgresExpress0.543s (-5.8% 🟢)1.023s (~)0.480s591.01x
💻 LocalNext.js (Turbopack)0.587s (-4.1%)1.005s (-1.7%)0.418s601.09x
💻 LocalNitro0.587s (+2.9%)1.005s (-1.6%)0.418s601.09x
💻 LocalExpress0.590s (-3.3%)1.005s (~)0.415s601.10x
🐘 PostgresNext.js (Turbopack)0.590s (+4.4%)1.024s (~)0.434s591.10x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.469s (+15.2% 🔺)5.358s (+6.2% 🔺)1.889s121.00x
▲ VercelExpress3.920s (+14.3% 🔺)5.535s (+2.0%)1.615s111.13x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.210s (-5.1% 🟢)2.007s (~)0.798s451.00x
🐘 PostgresExpress1.317s (-0.6%)2.029s (+1.1%)0.712s451.09x
🐘 PostgresNext.js (Turbopack)1.371s (+7.5% 🔺)2.008s (~)0.637s451.13x
💻 LocalExpress1.458s (-6.5% 🟢)2.006s (-1.2%)0.548s451.21x
💻 LocalNitro1.465s (+5.9% 🔺)2.006s (~)0.541s451.21x
💻 LocalNext.js (Turbopack)1.468s (~)2.006s (~)0.538s451.21x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express9.874s (+15.2% 🔺)11.844s (+13.6% 🔺)1.970s81.00x
▲ VercelNitro10.872s (+42.5% 🔺)12.748s (+34.2% 🔺)1.876s81.10x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.461s (-7.3% 🟢)3.058s (-2.5%)0.598s401.00x
🐘 PostgresExpress2.604s (-1.2%)3.085s (+0.9%)0.482s391.06x
🐘 PostgresNext.js (Turbopack)2.740s (+7.5% 🔺)3.010s (~)0.270s401.11x
💻 LocalNitro3.190s (+6.4% 🔺)3.880s (+12.9% 🔺)0.690s311.30x
💻 LocalExpress3.234s (-0.5%)3.977s (-0.8%)0.743s311.31x
💻 LocalNext.js (Turbopack)3.250s (+1.4%)3.978s (~)0.728s311.32x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro23.504s (+40.8% 🔺)25.845s (+35.8% 🔺)2.341s51.00x
▲ VercelExpress24.605s (+63.6% 🔺)26.637s (+54.7% 🔺)2.032s51.05x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.186s (+4.2%)1.007s (~)0.820s601.00x
🐘 PostgresNitro0.206s (-2.7%)1.006s (~)0.800s601.11x
🐘 PostgresExpress0.209s (-4.5%)1.006s (~)0.797s601.12x
💻 LocalNitro0.431s (+27.8% 🔺)1.005s (~)0.573s602.31x
💻 LocalExpress0.460s (+34.7% 🔺)1.005s (~)0.545s602.47x
💻 LocalNext.js (Turbopack)0.615s (+1.5%)1.022s (+1.7%)0.407s593.30x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.822s (+33.2% 🔺)3.467s (+11.1% 🔺)1.645s181.00x
▲ VercelExpress1.924s (+52.0% 🔺)3.820s (+29.2% 🔺)1.897s161.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Nitro | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.286s (+6.7% 🔺)1.007s (~)0.721s901.00x
🐘 PostgresNitro0.321s (-0.5%)1.006s (~)0.685s901.12x
🐘 PostgresExpress0.328s (+2.1%)1.006s (~)0.678s901.15x
💻 LocalNitro2.078s (+2.6%)2.637s (+6.8% 🔺)0.559s357.27x
💻 LocalExpress2.147s (+9.8% 🔺)2.737s (+10.9% 🔺)0.590s337.51x
💻 LocalNext.js (Turbopack)2.862s (+7.3% 🔺)3.341s (+8.6% 🔺)0.480s2710.01x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.070s (+80.9% 🔺)4.924s (+39.3% 🔺)1.854s191.00x
▲ VercelNitro3.838s (+126.4% 🔺)5.752s (+60.2% 🔺)1.914s161.25x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Next.js (Turbopack)0.512s (+6.2% 🔺)3.060s (+0.9%)2.549s401.00x
🐘 PostgresExpress0.512s (+3.8%)1.059s (+4.4%)0.547s1141.00x
🐘 PostgresNitro0.515s (-1.8%)1.128s (+7.5% 🔺)0.613s1071.01x
💻 LocalNext.js (Turbopack)9.547s (-5.1% 🟢)10.445s (-6.0% 🟢)0.898s1218.66x
💻 LocalExpress9.729s (-0.6%)11.032s (+3.9%)1.304s1119.02x
💻 LocalNitro10.101s (+8.0% 🔺)10.862s (+7.4% 🔺)0.761s1219.75x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.023s (+65.9% 🔺)5.821s (+33.0% 🔺)1.798s211.00x
▲ VercelNitro4.281s (+94.3% 🔺)6.434s (+56.6% 🔺)2.153s191.06x
▲ VercelNext.js (Turbopack)⚠️missing----

🔍 Observability: Express | Nitro

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Next.js (Turbopack)1.142s (-1.0%)1.967s (-1.8%)0.012s (-1.6%)2.019s (~)0.877s101.00x
🐘 PostgresExpress1.153s (-2.1%)2.000s (~)0.001s (-14.3% 🟢)2.010s (~)0.857s101.01x
💻 LocalExpress1.156s (-1.6%)2.005s (~)0.012s (-1.6%)2.020s (~)0.864s101.01x
💻 LocalNitro1.158s (+0.7%)2.004s (~)0.011s (+23.9% 🔺)2.018s (~)0.861s101.01x
🐘 PostgresNitro1.179s (+0.8%)1.998s (~)0.001s (-42.1% 🟢)2.010s (~)0.831s101.03x
🐘 PostgresNext.js (Turbopack)1.195s (+2.1%)2.001s (~)0.001s (+16.7% 🔺)2.013s (~)0.818s101.05x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.353s (+9.2% 🔺)3.839s (+12.5% 🔺)3.558s (+123.6% 🔺)7.971s (+42.8% 🔺)5.618s101.00x
▲ VercelExpress2.793s (+23.7% 🔺)3.674s (+7.8% 🔺)3.561s (+31.5% 🔺)7.812s (+14.6% 🔺)5.018s101.19x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Nitro | Express

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.535s (-2.8%)2.010s (~)0.012s (+1.9%)2.026s (~)0.491s301.00x
💻 LocalExpress1.548s (-2.3%)2.009s (~)0.013s (+4.6%)2.025s (~)0.477s301.01x
🐘 PostgresNitro1.554s (-5.4% 🟢)2.003s (-1.7%)0.005s (+4.7%)2.025s (-1.6%)0.471s301.01x
💻 LocalNext.js (Turbopack)1.562s (-3.5%)1.971s (-1.8%)0.012s (-3.9%)2.026s (~)0.464s301.02x
🐘 PostgresExpress1.566s (-1.2%)2.006s (~)0.005s (-0.7%)2.025s (~)0.459s301.02x
🐘 PostgresNext.js (Turbopack)1.669s (+4.3%)2.011s (~)0.005s (+6.8% 🔺)2.027s (~)0.358s301.09x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express7.872s (+28.4% 🔺)9.374s (+19.5% 🔺)0.589s (+107.7% 🔺)10.643s (+22.7% 🔺)2.770s61.00x
▲ VercelNitro8.516s (+48.8% 🔺)9.855s (+30.1% 🔺)0.841s (+171.2% 🔺)11.244s (+33.5% 🔺)2.728s61.08x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.775s (+1.6%)1.059s (~)0.000s (+Infinity% 🔺)1.087s (+0.7%)0.311s561.00x
🐘 PostgresNitro0.807s (+4.9%)1.107s (~)0.000s (+35.8% 🔺)1.140s (+1.9%)0.334s531.04x
🐘 PostgresNext.js (Turbopack)1.001s (+31.5% 🔺)1.396s (+28.3% 🔺)0.000s (+32.6% 🔺)1.404s (+28.1% 🔺)0.403s431.29x
💻 LocalExpress1.257s (-5.0%)2.013s (~)0.001s (+45.5% 🔺)2.016s (~)0.759s301.62x
💻 LocalNitro1.272s (-6.9% 🟢)2.014s (~)0.000s (-33.3% 🟢)2.017s (~)0.745s301.64x
💻 LocalNext.js (Turbopack)1.369s (-5.5% 🟢)1.979s (-1.6%)0.000s (+33.3% 🔺)2.016s (~)0.647s301.77x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.986s (+47.6% 🔺)6.398s (+26.8% 🔺)0.000s (-100.0% 🟢)6.908s (+24.2% 🔺)1.922s91.00x
▲ VercelNitro5.214s (+9.7% 🔺)6.241s (-5.3% 🟢)0.000s (NaN%)6.993s (-1.8%)1.779s91.05x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.579s (+3.3%)2.181s (+3.8%)0.000s (+211.1% 🔺)2.224s (+3.3%)0.644s271.00x
🐘 PostgresNitro1.761s (+6.4% 🔺)2.304s (+4.0%)0.000s (-100.0% 🟢)2.333s (+4.6%)0.572s261.12x
🐘 PostgresNext.js (Turbopack)2.551s (+33.6% 🔺)3.004s (+18.1% 🔺)0.000s (NaN%)3.012s (+18.1% 🔺)0.462s201.61x
💻 LocalExpress3.487s (-4.2%)4.160s (-1.6%)0.001s (+20.0% 🔺)4.164s (-1.6%)0.677s152.21x
💻 LocalNitro3.539s (+1.1%)4.090s (+3.2%)0.001s (-23.0% 🟢)4.096s (+3.1%)0.557s152.24x
💻 LocalNext.js (Turbopack)3.587s (-12.9% 🟢)4.061s (-11.7% 🟢)0.001s (-22.2% 🟢)4.102s (-11.0% 🟢)0.515s152.27x

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express6.861s (-16.9% 🟢)7.886s (-20.1% 🟢)0.000s (-25.0% 🟢)8.548s (-18.2% 🟢)1.687s81.00x
▲ VercelNitro7.109s (+24.9% 🔺)8.494s (+19.0% 🔺)0.000s (-100.0% 🟢)9.026s (+17.0% 🔺)1.917s71.04x
▲ VercelNext.js (Turbopack)⚠️missing-----

🔍 Observability: Express | Nitro

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalExpress9/21
🐘 PostgresNitro10/21
▲ VercelExpress12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres16/21
Next.js (Turbopack)🐘 Postgres13/21
Nitro🐘 Postgres14/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)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production144202301672
✅ 💻 Local Development160502191824
✅ 📦 Local Production160502191824
✅ 🐘 Local Postgres159302311824
✅ 🪟 Windows15200152
✅ 📋 Other88501791064
Total7282010788360

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro125027
✅ example125027
✅ express125027
✅ fastify125027
✅ hono125027
✅ nextjs-turbopack14903
✅ nextjs-webpack14903
✅ nitro125027
✅ nuxt125027
✅ sveltekit14408
✅ vite125027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable127025
✅ express-stable127025
✅ fastify-stable127025
✅ hono-stable127025
✅ nextjs-turbopack-canary133019
✅ nextjs-turbopack-stable15200
✅ nextjs-webpack-canary133019
✅ nextjs-webpack-stable15200
✅ nitro-stable127025
✅ nuxt-stable127025
✅ sveltekit-stable14606
✅ vite-stable127025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable126026
✅ express-stable126026
✅ fastify-stable126026
✅ hono-stable126026
✅ nextjs-turbopack-canary132020
✅ nextjs-turbopack-stable15101
✅ nextjs-webpack-canary132020
✅ nextjs-webpack-stable15101
✅ nitro-stable126026
✅ nuxt-stable126026
✅ sveltekit-stable14507
✅ vite-stable126026
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15200
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable127025
✅ e2e-local-dev-tanstack-start-127025
✅ e2e-local-postgres-nest-stable126026
✅ e2e-local-postgres-tanstack-start-126026
✅ e2e-local-prod-nest-stable127025
✅ e2e-local-prod-tanstack-start-127025
✅ e2e-vercel-prod-tanstack-start125027

📋 View full workflow run

'@workflow/world-vercel': patch
---

Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Suggested change
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, trimming the run_started request the first step start waits behind.
Turbo mode now tells world-vercel to skip the run_started event-log preload it never reads, reducing request time.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Applied in f7a2b22.

@VaguelySerious
VaguelySerious marked this pull request as ready for review June 22, 2026 21:06
@VaguelySerious
VaguelySerious requested review from a team and ijjk as code ownersJune 22, 2026 21:06

@pranaygppranaygp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the full diff and traced the data path end-to-end (runtime.tsworld/CreateEventParamsworld-vercel/events.tsevents-v4.ts frame meta). This is a clean, well-scoped optimization and I don't see any correctness issues.

Key things I verified:

  • The backgrounded run_started result is genuinely never read under turbo — runReadyBarrier is typed Promise<unknown> and only ever awaited as an ordering barrier, and preloadedEvents is hard-forced to []. So skipEventPreload only suppresses already-dead server work; it doesn't change SDK behavior.
  • Redelivery (attempt > 1) is correctly excluded (turbo requires attempt === 1), so it still consumes the preload — covered by the new redeliver test.
  • Fully additive/back-compat: the flag is only forwarded when truthy, only acted on for run_started, and the runtime always falls back to events.list. Old server ignores the meta key; new server + old SDK never sends it.
  • Ran the affected suites locally after building deps: packages/core (1320 passed, incl. the new skip the run_started preload test) and packages/world-vercel (165 passed, incl. both new events-v4 tests).

One optional, non-blocking naming nit left inline. LGTM.

Comment threadpackages/world-vercel/src/events.ts Outdated
// barrier only and never reads the preloaded log, so tell the server to
// skip the list+resolve. The server only acts on it for run_started;
// older servers ignore it and simply preload as before.
...(params?.skipEventPreload ? { skipPreload: true } : {}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Optional / non-blocking: the concept is named skipEventPreload at the World boundary (CreateEventParams) but skipPreload on the wire (CreateEventV4Input + frame meta). The analogous inline-delta feature (sinceCursor) keeps a single name all the way through, so the divergence here is a bit surprising and slightly hurts greppability — someone searching skipPreload won't find the runtime/World side and vice-versa.

If the wire name skipPreload is fixed by the server contract, this is fine as-is (the comments document the mapping well). Just flagging in case unifying on one name is cheap.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

(AI) Good call — unified on skipPreload end-to-end in f7a2b22: renamed the World-boundary CreateEventParams.skipEventPreloadskipPreload (runtime call site + tests updated), so it now greps across the SDK, the v4 frame meta, and the backend CreateEventOptions.skipPreload, matching the sinceCursor single-name precedent.

- Rename the World-boundary param `skipEventPreload` -> `skipPreload` so the
single name greps across the SDK, the v4 frame meta, and the backend option
(matching the `sinceCursor` precedent). Per @pranaygp review.
- Apply @VaguelySerious changeset wording suggestion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VaguelySerious
VaguelySerious merged commit d108ba3 into mainJun 22, 2026
181 of 184 checks passed
@VaguelySerious
VaguelySerious deleted the peter/turbo-skip-run-started-preload branch June 22, 2026 22:53
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for d108ba3 (AI decision).

This change is an optimization to turbo mode, which does not exist on stable — I verified that runReadyBarrier, driveTurbo, skipPreload, and the parallel sinceCursor field are all absent from runtime.ts, runtime.test.ts, and the world-vercel event files on stable, and the v5 turbo-mode changelog doc it edits is not present there either. Since the new skipPreload flag is set exclusively on the turbo-backgrounded run_started write barrier, it builds directly on main-only behavior and has no place to apply on stable.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

d108ba32a76d516deadaa7264aec79412d862626

pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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

@VaguelySerious@pranaygp