Skip to content

[tests] Re-enable concurrent e2e suite#2083

Draft
VaguelySerious wants to merge 6 commits into
mainfrom
peter/enable-e2e-concurrency
Draft

[tests] Re-enable concurrent e2e suite#2083
VaguelySerious wants to merge 6 commits into
mainfrom
peter/enable-e2e-concurrency

Conversation

@VaguelySerious
Copy link
Copy Markdown
Member

Summary

  • Re-enables describe.concurrent in packages/core/e2e/e2e.test.ts, which was made sequential in 78048e0 ("no concurrency") with a TODO to re-enable.
  • Each workbench currently runs ~87 e2e tests serially against its preview deploy; this is the dominant ~15-minute cost per matrix entry.
  • This is a draft to see which (if any) tests are still flake-prone under concurrency after recent fixes (e.g. the abort-fetch class of flakes in [tests] Fix abort-fetch e2e flake #2081).

Test plan

  • All workbench matrix entries (E2E Vercel Prod) pass
  • Compare wall-clock vs. recent main runs
  • If failures cluster around specific tests, mark them .sequential rather than reverting the whole flip

Notes

If concurrency exposes real isolation bugs (shared identifiers, cross-test state), I'll fix those before unwinding the draft state. If it's only known-flaky externals, those should already have been addressed in #2081 / follow-ups.

🤖 Generated with Claude Code

Flips packages/core/e2e/e2e.test.ts back to describe.concurrent. The
suite was made sequential ("temporarily disabling concurrent tests to
avoid flakiness") and never re-enabled. Each workbench now runs ~87
tests serially against its preview deploy, dominating CI wall-clock.

Putting this up as a draft to see which (if any) tests are still
flake-prone under concurrency, after recent fixes to the abort-fetch
class of flakes.
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 22, 2026

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

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Error Error May 23, 2026 1:38pm
example-nextjs-workflow-webpack Ready Ready Preview, Comment May 23, 2026 1:38pm
example-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-astro-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-express-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-fastify-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-hono-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-nitro-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-nuxt-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-sveltekit-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-tanstack-start-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workbench-vite-workflow Ready Ready Preview, Comment May 23, 2026 1:38pm
workflow-docs Ready Ready Preview, Comment, Open in v0 May 23, 2026 1:38pm
workflow-swc-playground Ready Ready Preview, Comment May 23, 2026 1:38pm
workflow-tarballs Ready Ready Preview, Comment May 23, 2026 1:38pm
workflow-web Ready Ready Preview, Comment May 23, 2026 1:38pm

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 22, 2026

🦋 Changeset detected

Latest commit: c7060b1

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

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

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

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

📊 Benchmark Results

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

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 0.032s (-26.0% 🟢) 1.006s (~) 0.974s 10 1.00x
💻 Local Express 0.032s (-26.9% 🟢) 1.006s (~) 0.974s 10 1.02x
💻 Local Next.js (Turbopack) 0.034s 1.005s 0.972s 10 1.06x
🐘 Postgres Express 0.050s (-13.1% 🟢) 1.012s (~) 0.961s 10 1.58x
🐘 Postgres Nitro 0.051s (-46.3% 🟢) 1.013s (-2.9%) 0.962s 10 1.60x
🐘 Postgres Next.js (Turbopack) 0.056s 1.011s 0.955s 10 1.77x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 0.306s (+21.6% 🔺) 2.546s (+9.1% 🔺) 2.240s 10 1.00x
▲ Vercel Nitro 0.426s (+4.0%) 2.554s (+1.8%) 2.128s 10 1.39x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.076s (-4.9%) 2.007s (~) 0.931s 10 1.00x
💻 Local Express 1.079s (-4.1%) 2.007s (~) 0.928s 10 1.00x
🐘 Postgres Nitro 1.082s (-5.1% 🟢) 2.008s (~) 0.926s 10 1.01x
🐘 Postgres Express 1.087s (-5.2% 🟢) 2.009s (~) 0.922s 10 1.01x
💻 Local Next.js (Turbopack) 1.089s 2.005s 0.916s 10 1.01x
🐘 Postgres Next.js (Turbopack) 1.117s 2.008s 0.891s 10 1.04x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 1.806s (-53.6% 🟢) 3.829s (-35.2% 🟢) 2.023s 10 1.00x
▲ Vercel Next.js (Turbopack) 1.906s (-6.3% 🟢) 3.724s (-2.8%) 1.818s 10 1.06x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 10.387s (-4.4%) 11.018s (~) 0.630s 3 1.00x
💻 Local Express 10.434s (-4.5%) 11.023s (~) 0.590s 3 1.00x
💻 Local Nitro 10.434s (-4.7%) 11.024s (~) 0.590s 3 1.00x
🐘 Postgres Express 10.435s (-4.8%) 11.014s (~) 0.579s 3 1.00x
💻 Local Next.js (Turbopack) 10.493s 11.021s 0.528s 3 1.01x
🐘 Postgres Next.js (Turbopack) 10.702s 11.020s 0.318s 3 1.03x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 13.961s (-41.2% 🟢) 16.231s (-35.4% 🟢) 2.269s 2 1.00x
▲ Vercel Next.js (Turbopack) 14.589s (-15.8% 🟢) 16.525s (-14.8% 🟢) 1.936s 2 1.04x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 13.428s (-8.0% 🟢) 14.016s (-6.7% 🟢) 0.588s 5 1.00x
🐘 Postgres Express 13.500s (-7.4% 🟢) 14.019s (-6.7% 🟢) 0.518s 5 1.01x
💻 Local Express 13.527s (-9.6% 🟢) 14.027s (-6.7% 🟢) 0.500s 5 1.01x
💻 Local Nitro 13.592s (-9.8% 🟢) 14.027s (-12.5% 🟢) 0.435s 5 1.01x
💻 Local Next.js (Turbopack) 13.761s 14.025s 0.264s 5 1.02x
🐘 Postgres Next.js (Turbopack) 14.104s 15.019s 0.915s 4 1.05x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 21.896s (-66.0% 🟢) 23.781s (-64.3% 🟢) 1.885s 3 1.00x
▲ Vercel Next.js (Turbopack) 22.228s (-57.7% 🟢) 24.764s (-54.7% 🟢) 2.536s 3 1.02x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 11.854s (-15.1% 🟢) 12.015s (-16.0% 🟢) 0.161s 8 1.00x
💻 Local Nitro 11.923s (-29.0% 🟢) 12.021s (-29.4% 🟢) 0.098s 8 1.01x
🐘 Postgres Express 11.984s (-14.4% 🟢) 12.017s (-17.7% 🟢) 0.033s 8 1.01x
💻 Local Express 12.021s (-27.6% 🟢) 12.399s (-27.2% 🟢) 0.379s 8 1.01x
💻 Local Next.js (Turbopack) 12.282s 13.022s 0.740s 7 1.04x
🐘 Postgres Next.js (Turbopack) 13.164s 14.015s 0.851s 7 1.11x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 31.366s (-92.6% 🟢) 33.410s (-92.1% 🟢) 2.044s 3 1.00x
▲ Vercel Next.js (Turbopack) 32.382s (-91.8% 🟢) 34.323s (-91.3% 🟢) 1.940s 3 1.03x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.158s (-9.2% 🟢) 2.009s (~) 0.851s 15 1.00x
🐘 Postgres Express 1.160s (-8.0% 🟢) 2.008s (~) 0.848s 15 1.00x
💻 Local Nitro 1.172s (-28.2% 🟢) 2.006s (-3.3%) 0.835s 15 1.01x
💻 Local Express 1.179s (-20.8% 🟢) 2.007s (~) 0.828s 15 1.02x
💻 Local Next.js (Turbopack) 1.212s 2.005s 0.793s 15 1.05x
🐘 Postgres Next.js (Turbopack) 1.218s 2.008s 0.790s 15 1.05x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.877s (+2.1%) 4.515s (+4.5%) 1.638s 8 1.00x
▲ Vercel Next.js (Turbopack) 2.967s (-12.7% 🟢) 4.728s (-4.2%) 1.761s 7 1.03x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.212s (-48.6% 🟢) 2.007s (-33.3% 🟢) 0.795s 15 1.00x
🐘 Postgres Nitro 1.224s (-47.9% 🟢) 2.009s (-33.2% 🟢) 0.785s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.336s 2.007s 0.671s 15 1.10x
💻 Local Next.js (Turbopack) 1.524s 2.004s 0.480s 15 1.26x
💻 Local Nitro 1.744s (-44.5% 🟢) 2.007s (-48.3% 🟢) 0.264s 15 1.44x
💻 Local Express 1.835s (-37.8% 🟢) 2.140s (-38.0% 🟢) 0.304s 15 1.51x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 4.146s (-41.6% 🟢) 6.056s (-32.0% 🟢) 1.910s 5 1.00x
▲ Vercel Nitro 5.247s (+29.5% 🔺) 7.231s (+22.1% 🔺) 1.984s 5 1.27x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.339s (-61.6% 🟢) 2.007s (-49.9% 🟢) 0.669s 15 1.00x
🐘 Postgres Nitro 1.358s (-61.0% 🟢) 2.007s (-49.9% 🟢) 0.649s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.617s 2.007s 0.390s 15 1.21x
💻 Local Next.js (Turbopack) 3.177s 3.453s 0.276s 9 2.37x
💻 Local Express 5.435s (-34.8% 🟢) 6.214s (-31.2% 🟢) 0.779s 5 4.06x
💻 Local Nitro 5.468s (-34.5% 🟢) 6.012s (-33.3% 🟢) 0.544s 5 4.08x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 6.778s (+92.3% 🔺) 8.495s (+53.5% 🔺) 1.716s 4 1.00x
▲ Vercel Next.js (Turbopack) 8.699s (-2.4%) 11.031s (+0.6%) 2.332s 3 1.28x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.142s (-9.1% 🟢) 2.009s (~) 0.866s 15 1.00x
🐘 Postgres Nitro 1.152s (-8.3% 🟢) 2.008s (~) 0.856s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.209s 2.008s 0.800s 15 1.06x
💻 Local Next.js (Turbopack) 1.209s 2.004s 0.795s 15 1.06x
💻 Local Nitro 1.417s (-24.1% 🟢) 2.006s (-14.3% 🟢) 0.590s 15 1.24x
💻 Local Express 1.427s (-24.7% 🟢) 2.006s (-15.1% 🟢) 0.580s 15 1.25x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.873s (-2.0%) 4.428s (-4.6%) 1.555s 7 1.00x
▲ Vercel Nitro 2.925s (+18.9% 🔺) 5.006s (+20.1% 🔺) 2.081s 6 1.02x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.214s (-48.1% 🟢) 2.008s (-33.3% 🟢) 0.794s 15 1.00x
🐘 Postgres Express 1.226s (-47.6% 🟢) 2.009s (-33.3% 🟢) 0.783s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.343s 2.009s 0.666s 15 1.11x
💻 Local Next.js (Turbopack) 1.579s 2.005s 0.426s 15 1.30x
💻 Local Nitro 2.034s (-33.6% 🟢) 2.510s (-35.4% 🟢) 0.475s 12 1.68x
💻 Local Express 2.057s (-34.3% 🟢) 2.508s (-33.3% 🟢) 0.451s 12 1.69x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.368s (+4.2%) 5.319s (+4.8%) 1.951s 6 1.00x
▲ Vercel Next.js (Turbopack) 4.111s (+30.8% 🔺) 5.838s (+29.1% 🔺) 1.726s 6 1.22x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.316s (-62.2% 🟢) 2.009s (-49.9% 🟢) 0.693s 15 1.00x
🐘 Postgres Express 1.334s (-61.9% 🟢) 2.007s (-50.0% 🟢) 0.673s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.644s 2.008s 0.364s 15 1.25x
💻 Local Next.js (Turbopack) 3.454s 4.012s 0.558s 8 2.62x
💻 Local Express 5.760s (-34.6% 🟢) 6.216s (-33.0% 🟢) 0.456s 5 4.38x
💻 Local Nitro 5.993s (-34.5% 🟢) 6.513s (-35.0% 🟢) 0.521s 6 4.55x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 5.982s (-11.5% 🟢) 7.562s (-11.5% 🟢) 1.580s 4 1.00x
▲ Vercel Nitro 6.436s (+26.4% 🔺) 8.067s (+18.3% 🔺) 1.632s 4 1.08x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.428s (-47.8% 🟢) 1.006s (~) 0.578s 60 1.00x
🐘 Postgres Express 0.467s (-44.3% 🟢) 1.006s (-1.7%) 0.539s 60 1.09x
💻 Local Nitro 0.493s (-49.7% 🟢) 1.022s (-6.6% 🟢) 0.529s 59 1.15x
💻 Local Express 0.517s (-47.4% 🟢) 1.022s (-5.0% 🟢) 0.504s 59 1.21x
💻 Local Next.js (Turbopack) 0.615s 1.021s 0.406s 59 1.44x
🐘 Postgres Next.js (Turbopack) 0.675s 1.006s 0.332s 60 1.58x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.901s (-73.2% 🟢) 7.712s (-67.9% 🟢) 1.811s 8 1.00x
▲ Vercel Next.js (Turbopack) 6.006s (-58.6% 🟢) 7.961s (-50.5% 🟢) 1.956s 8 1.02x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.995s (-48.4% 🟢) 1.350s (-35.7% 🟢) 0.355s 67 1.00x
🐘 Postgres Express 1.188s (-39.9% 🟢) 1.922s (-14.9% 🟢) 0.734s 47 1.19x
💻 Local Nitro 1.220s (-59.8% 🟢) 2.006s (-46.6% 🟢) 0.786s 45 1.23x
💻 Local Express 1.260s (-58.2% 🟢) 2.007s (-44.0% 🟢) 0.746s 45 1.27x
💻 Local Next.js (Turbopack) 1.421s 2.004s 0.583s 45 1.43x
🐘 Postgres Next.js (Turbopack) 1.660s 2.008s 0.347s 45 1.67x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 16.140s (-59.1% 🟢) 18.101s (-56.2% 🟢) 1.961s 6 1.00x
▲ Vercel Next.js (Turbopack) 16.668s (-66.5% 🟢) 19.003s (-63.3% 🟢) 2.335s 5 1.03x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.994s (-51.4% 🟢) 2.335s (-49.3% 🟢) 0.341s 52 1.00x
🐘 Postgres Express 2.106s (-47.2% 🟢) 2.697s (-38.3% 🟢) 0.591s 45 1.06x
💻 Local Nitro 2.786s (-70.0% 🟢) 3.058s (-69.5% 🟢) 0.272s 40 1.40x
💻 Local Express 2.801s (-69.6% 🟢) 3.033s (-69.7% 🟢) 0.231s 40 1.41x
🐘 Postgres Next.js (Turbopack) 3.212s 4.009s 0.797s 30 1.61x
💻 Local Next.js (Turbopack) 3.466s 4.074s 0.608s 30 1.74x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 27.620s (-71.5% 🟢) 29.816s (-69.7% 🟢) 2.196s 5 1.00x
▲ Vercel Next.js (Turbopack) 32.787s (-69.4% 🟢) 35.186s (-67.7% 🟢) 2.399s 4 1.19x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.190s (-33.1% 🟢) 1.006s (~) 0.816s 60 1.00x
🐘 Postgres Express 0.198s (-30.0% 🟢) 1.023s (+1.5%) 0.825s 59 1.04x
🐘 Postgres Next.js (Turbopack) 0.230s 1.006s 0.776s 60 1.21x
💻 Local Next.js (Turbopack) 0.337s 1.003s 0.666s 60 1.78x
💻 Local Express 0.381s (-32.0% 🟢) 1.004s (~) 0.623s 60 2.01x
💻 Local Nitro 0.399s (-34.0% 🟢) 1.004s (-1.7%) 0.605s 60 2.11x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.453s (+47.7% 🔺) 4.362s (+30.2% 🔺) 1.909s 14 1.00x
▲ Vercel Next.js (Turbopack) 2.813s (+39.1% 🔺) 4.846s (+27.8% 🔺) 2.034s 13 1.15x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.284s (-42.8% 🟢) 1.006s (~) 0.722s 90 1.00x
🐘 Postgres Express 0.308s (-39.6% 🟢) 1.006s (~) 0.698s 90 1.08x
🐘 Postgres Next.js (Turbopack) 0.435s 1.006s 0.571s 90 1.53x
💻 Local Next.js (Turbopack) 1.433s 2.028s 0.595s 45 5.05x
💻 Local Express 2.159s (-14.1% 🟢) 2.715s (-9.8% 🟢) 0.556s 34 7.60x
💻 Local Nitro 2.171s (-14.5% 🟢) 2.884s (-4.1%) 0.713s 32 7.65x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.296s (+64.2% 🔺) 6.881s (+42.7% 🔺) 1.585s 14 1.00x
▲ Vercel Next.js (Turbopack) 6.720s (+90.1% 🔺) 8.608s (+65.8% 🔺) 1.888s 11 1.27x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.583s (-26.2% 🟢) 1.006s (~) 0.422s 120 1.00x
🐘 Postgres Express 0.652s (-20.4% 🟢) 1.006s (-1.1%) 0.355s 120 1.12x
🐘 Postgres Next.js (Turbopack) 0.890s 1.078s 0.188s 112 1.53x
💻 Local Next.js (Turbopack) 6.974s 7.706s 0.731s 16 11.96x
💻 Local Nitro 10.196s (-8.9% 🟢) 10.777s (-7.6% 🟢) 0.581s 12 17.48x
💻 Local Express 10.526s (-5.9% 🟢) 11.031s (-7.6% 🟢) 0.505s 11 18.04x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 15.606s (+51.1% 🔺) 17.743s (+44.4% 🔺) 2.137s 7 1.00x
▲ Vercel Nitro 16.197s (+109.7% 🔺) 18.211s (+93.7% 🔺) 2.014s 7 1.04x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.128s (+450.3% 🔺) 2.001s (+100.2% 🔺) 0.001s (-33.3% 🟢) 2.010s (+98.8% 🔺) 0.882s 10 1.00x
💻 Local Next.js (Turbopack) 1.129s 2.002s 0.006s 2.011s 0.882s 10 1.00x
💻 Local Nitro 1.133s (+430.0% 🔺) 2.005s (+99.6% 🔺) 0.013s (+4.0%) 2.020s (+98.3% 🔺) 0.888s 10 1.00x
💻 Local Express 1.138s (+471.7% 🔺) 2.006s (+99.7% 🔺) 0.013s (+5.8% 🔺) 2.021s (+98.5% 🔺) 0.883s 10 1.01x
🐘 Postgres Express 1.145s (+458.3% 🔺) 2.001s (+100.4% 🔺) 0.001s (-18.8% 🟢) 2.010s (+98.7% 🔺) 0.865s 10 1.01x
🐘 Postgres Next.js (Turbopack) 1.201s 2.001s 0.002s 2.010s 0.809s 10 1.06x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.444s (-64.3% 🟢) 3.510s (-59.4% 🟢) 2.280s (+260.8% 🔺) 6.380s (-34.8% 🟢) 3.936s 10 1.00x
▲ Vercel Nitro 2.490s (-35.0% 🟢) 3.601s (-31.8% 🟢) 13.675s (+1742.7% 🔺) 17.941s (+176.7% 🔺) 15.451s 10 1.02x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Next.js (Turbopack) 1.475s 2.007s 0.006s 2.015s 0.540s 30 1.00x
🐘 Postgres Nitro 1.494s (+139.3% 🔺) 2.002s (+98.9% 🔺) 0.004s (+6.4% 🔺) 2.027s (+98.3% 🔺) 0.534s 30 1.01x
💻 Local Nitro 1.541s (+83.7% 🔺) 2.013s (+98.9% 🔺) 0.010s (+4.9%) 2.025s (+81.5% 🔺) 0.484s 30 1.04x
🐘 Postgres Express 1.543s (+144.9% 🔺) 2.004s (+99.1% 🔺) 0.004s (+3.6%) 2.028s (+98.2% 🔺) 0.484s 30 1.05x
💻 Local Express 1.549s (+104.6% 🔺) 2.013s (+95.7% 🔺) 0.010s (+9.4% 🔺) 2.026s (+94.8% 🔺) 0.476s 30 1.05x
🐘 Postgres Next.js (Turbopack) 1.678s 2.010s 0.004s 2.025s 0.347s 30 1.14x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 5.989s (-64.6% 🟢) 7.269s (-60.1% 🟢) 0.284s (+34.4% 🔺) 8.226s (-56.6% 🟢) 2.237s 8 1.00x
▲ Vercel Nitro 6.280s (-78.7% 🟢) 7.470s (-75.8% 🟢) 0.267s (+138.6% 🔺) 8.303s (-73.9% 🟢) 2.023s 8 1.05x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.640s (-34.0% 🟢) 1.012s (-18.8% 🟢) 0.000s (+22.0% 🔺) 1.030s (-18.1% 🟢) 0.391s 59 1.00x
🐘 Postgres Express 0.664s (-30.9% 🟢) 1.011s (-20.9% 🟢) 0.000s (-61.0% 🟢) 1.032s (-21.0% 🟢) 0.369s 59 1.04x
🐘 Postgres Next.js (Turbopack) 0.766s 1.017s 0.000s 1.032s 0.266s 59 1.20x
💻 Local Next.js (Turbopack) 1.042s 1.631s 0.000s 1.634s 0.592s 37 1.63x
💻 Local Express 1.344s (+9.7% 🔺) 2.016s (~) 0.000s (-30.0% 🟢) 2.018s (~) 0.674s 30 2.10x
💻 Local Nitro 1.373s (+12.3% 🔺) 2.016s (~) 0.000s (+66.7% 🔺) 2.018s (~) 0.645s 30 2.15x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.957s (+29.7% 🔺) 5.319s (+21.1% 🔺) 0.000s (+18.2% 🔺) 5.894s (+22.6% 🔺) 1.937s 11 1.00x
▲ Vercel Next.js (Turbopack) 3.981s (-60.9% 🟢) 5.285s (-54.1% 🟢) 0.000s (+Infinity% 🔺) 5.843s (-51.5% 🟢) 1.862s 11 1.01x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

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

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.278s (-28.7% 🟢) 2.029s (-5.2% 🟢) 0.000s (-100.0% 🟢) 2.049s (-5.7% 🟢) 0.771s 30 1.00x
🐘 Postgres Express 1.384s (-21.9% 🟢) 2.029s (-6.8% 🟢) 0.000s (+Infinity% 🔺) 2.044s (-7.1% 🟢) 0.659s 30 1.08x
🐘 Postgres Next.js (Turbopack) 1.500s 2.145s 0.000s 2.153s 0.654s 28 1.17x
💻 Local Next.js (Turbopack) 2.061s 2.523s 0.000s 2.528s 0.467s 24 1.61x
💻 Local Express 3.109s (-10.3% 🟢) 3.781s (-6.3% 🟢) 0.001s (-21.9% 🟢) 3.784s (-6.3% 🟢) 0.675s 16 2.43x
💻 Local Nitro 3.183s (-6.0% 🟢) 3.903s (-3.2%) 0.000s (-18.0% 🟢) 3.906s (-3.2%) 0.723s 16 2.49x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.980s (+46.1% 🔺) 7.651s (+42.4% 🔺) 0.000s (-54.2% 🟢) 8.181s (+41.2% 🔺) 2.201s 8 1.00x
▲ Vercel Next.js (Turbopack) 6.105s (+8.7% 🔺) 7.426s (+6.4% 🔺) 0.000s (~) 7.952s (+5.5% 🔺) 1.847s 8 1.02x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

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

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 17/21
Next.js (Turbopack) 🐘 Postgres 11/21
Nitro 🐘 Postgres 19/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
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

🧪 E2E Test Results

Some tests failed

Summary

Passed Failed Skipped Total
❌ ▲ Vercel Production 1219 3 219 1441
❌ 💻 Local Development 1610 5 219 1834
❌ 📦 Local Production 1614 1 219 1834
❌ 🐘 Local Postgres 1502 1 200 1703
✅ 🪟 Windows 131 0 0 131
❌ 📋 Other 740 1 176 917
Total 6816 11 1033 7860

❌ Failed Tests

▲ Vercel Production (3 failed)

nitro (1 failed):

  • outputStreamInsideStepWorkflow - getWritable() called inside step functions | wrun_01KS7ZJGW73X7CKYTEQBGY87E5 | 🔍 observability

nuxt (1 failed):

  • hookWorkflow is not resumable via public webhook endpoint | wrun_01KS7ZJ3YXC4E16B345GAMR59H | 🔍 observability

sveltekit (1 failed):

💻 Local Development (5 failed)

astro-stable (2 failed):

  • fibonacciWorkflow - recursive workflow composition via start() | wrun_01KS7ZKMSDH7F5ZJHKWBKZDJPQ
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps

nextjs-webpack-stable-lazy-discovery-disabled (1 failed):

  • error handling error propagation step errors basic step error preserves message and stack trace

nuxt-stable (1 failed):

  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps

sveltekit-stable (1 failed):

  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
📦 Local Production (1 failed)

nuxt-stable (1 failed):

  • error handling error propagation step errors basic step error preserves message and stack trace
🐘 Local Postgres (1 failed)

nuxt-stable (1 failed):

  • error handling error propagation step errors basic step error preserves message and stack trace
📋 Other (1 failed)

e2e-local-dev-tanstack-start- (1 failed):

  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps

Details by Category

❌ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 105 0 26
✅ example 105 0 26
✅ express 105 0 26
✅ fastify 105 0 26
✅ hono 105 0 26
✅ nextjs-turbopack 129 0 2
✅ nextjs-webpack 129 0 2
❌ nitro 104 1 26
❌ nuxt 104 1 26
❌ sveltekit 123 1 7
✅ vite 105 0 26
❌ 💻 Local Development
App Passed Failed Skipped
❌ astro-stable 104 2 25
✅ express-stable 106 0 25
✅ fastify-stable 106 0 25
✅ hono-stable 106 0 25
✅ nextjs-turbopack-canary 112 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 131 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 131 0 0
✅ nextjs-webpack-canary 112 0 19
❌ nextjs-webpack-stable-lazy-discovery-disabled 130 1 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 131 0 0
✅ nitro-stable 106 0 25
❌ nuxt-stable 105 1 25
❌ sveltekit-stable 124 1 6
✅ vite-stable 106 0 25
❌ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 106 0 25
✅ express-stable 106 0 25
✅ fastify-stable 106 0 25
✅ hono-stable 106 0 25
✅ nextjs-turbopack-canary 112 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 131 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 131 0 0
✅ nextjs-webpack-canary 112 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 131 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 131 0 0
✅ nitro-stable 106 0 25
❌ nuxt-stable 105 1 25
✅ sveltekit-stable 125 0 6
✅ vite-stable 106 0 25
❌ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 106 0 25
✅ express-stable 106 0 25
✅ fastify-stable 106 0 25
✅ hono-stable 106 0 25
✅ nextjs-turbopack-stable-lazy-discovery-disabled 131 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 131 0 0
✅ nextjs-webpack-canary 112 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 131 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 131 0 0
✅ nitro-stable 106 0 25
❌ nuxt-stable 105 1 25
✅ sveltekit-stable 125 0 6
✅ vite-stable 106 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 131 0 0
❌ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 106 0 25
❌ e2e-local-dev-tanstack-start- 105 1 25
✅ e2e-local-postgres-nest-stable 106 0 25
✅ e2e-local-postgres-tanstack-start- 106 0 25
✅ e2e-local-prod-nest-stable 106 0 25
✅ e2e-local-prod-tanstack-start- 106 0 25
✅ e2e-vercel-prod-tanstack-start 105 0 26

📋 View full workflow run


Some E2E test jobs failed:

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

Check the workflow run for details.

@VaguelySerious
Copy link
Copy Markdown
Member Author

CI verdict

Speedup is real. Per-workbench wall-clock dropped roughly 3×: from ~14–17 min on main to ~5–6 min here. Vitest's own run is even more dramatic — express went from ~15 min to 203s (~4–5× on the actual test phase).

But correctness regressed. 25 checks failed: every `E2E Vercel Prod Tests (*)` matrix entry except `nitro`, plus several `E2E Local Dev/Prod/Postgres` jobs and `E2E Windows Tests`.

Failure pattern

Every failure I sampled is the same shape: `Error: Test timed out in 60000ms`. The which tests fail varies per workbench — i.e. it's not a single broken test:

Workbench Failed test
express error handling > catchability > FatalError can be caught… (×2)
nuxt abortThrowIfAbortedWorkflow, step throw round-trips FatalError
astro abortDeterministicBranchFromStepWorkflow, abortListenerWorkflow, cross-file step error
hono FatalError fails immediately without retries
tanstack-start abortHookOrderingWorkflow (×2), abortReasonWorkflow
fastify abortHookOrderingWorkflow [hook-first-hook-first]
sveltekit FatalError fails immediately without retries
vite abortDeterministicBranchWorkflow, abortVoidSleepTimeoutWorkflow

The cluster is real though: AbortController + error-handling tests, which all do multiple sequential workflow round-trips and historically run close to the 60s budget.

Diagnosis

Default vitest `maxConcurrency` is 5. With five workflow runs hammering one workbench in parallel, the heavier multi-round-trip tests appear to queue past the per-test 60s budget. Local-Postgres/Prod/Dev also fail, so it's not Vercel-specific — workflow-server (local) and the in-process world also slow under contention.

Proposed next steps (separate PRs)

Holding off on bundling point (5) (shortening `sleep()` durations) into this PR — the suite isn't healthy enough to add another variable.

Three angles, in order of cheapest:

  1. Bump default `testTimeout` from 60s to ~180s (in `vitest.config.ts`). Cheap, but masks the queueing rather than fixing it. May allow individual tests to silently regress to 3× their real cost.
  2. Lower `maxConcurrency` to 3 (config-level or `describe.concurrent(name, { concurrent: 3 }, ...)`). Keeps most of the speedup, eases contention. Best first attempt IMO.
  3. Mark the error-handling and AbortController describes `.sequential` and leave the rest concurrent. Finest-grained, preserves max parallelism elsewhere, but requires per-block annotations.

Leaving this PR as draft for now. Happy to iterate as a follow-up.

The e2e suite tracked failed-run diagnostics via two module-level
mutables (`trackedRuns` and `currentTestName`) that every beforeEach
reset. Under describe.concurrent that races: when a test times out,
the displayed diagnostic typically belongs to whichever sibling task
most recently called setupRunTracking(). That's why PR #2083's first
CI run showed an unrelated `errorStepCrossFile` run as the
"diagnostic" for the FatalError catchability test that actually
timed out — leaving us blind to the real failure cause.

Switch to a `Map<taskId, PerTaskState>` keyed off
`getCurrentTest().id`, with the entry dropped via onTestFinished to
keep the map bounded. Also unconditionally log
`[trackRun] <test> → <runId>` so we can still correlate runs from
stdout even when diagnostics fetching itself stalls past the test's
deadline.
…Error type in readJSON

The previous writeExclusive used `fs.writeFile(path, data, { flag: 'wx' })`,
which is atomic for the file *creation* (O_CREAT|O_EXCL) but NOT for the
subsequent data write. A concurrent reader could catch the file with
zero bytes (or just `{`) before the writer's content reached the page
cache.

This race had been silently papered over by `readHookTokenClaim`, which
swallows any SyntaxError as "no claim exists" — which is wrong: a partial
write means a claim *does* exist, just not yet flushed, and treating it as
absent lets duplicate hook tokens through. PR #2083's concurrent e2e run
also surfaced the same race on runs/<id>.json creation, producing
size=0 byte run files in CI logs.

Fix: write content to a temp file first, then `link(2)` it atomically
into place. POSIX link is atomic and fails with EEXIST if the target
already exists, preserving the exclusive-claim semantics. Readers now
either see ENOENT or the fully-populated inode — never a half-written
file.

Also preserve the SyntaxError type when annotating readJSON failures
with file path / size / content snippet, so callers like
readHookTokenClaim that intentionally swallow `error instanceof SyntaxError`
continue to work (the previous diagnostic threw a plain Error and broke
them).
Vitest's default `maxConcurrency` of 5 saturates the workbench
preview deploys and the in-process world runtime under
`describe.concurrent`, pushing load-heavy tests (fibonacci tree
spawn, multi-step abort sequencing, AbortSignal.any composition)
into their per-test deadlines on PR #2083's run 4 even though
the same tests pass cleanly when run sequentially.

Drop to 3 in the root vitest config (only `test:e2e` and `bench`
consume it — per-package configs are untouched). The Vercel-deploy
matrix went from ~14-17min sequential → ~5-6min at concurrency 5;
trading some of that headroom for stability is the right call now
that the isolation/correctness fixes have landed.
Dropping vitest's default concurrency cap from 5 to 3 (commit c7060b1)
didn't reduce the remaining e2e flake count — runs 3/4 at default
concurrency=5 and run 5 at concurrency=3 all landed on exactly 15
failures. The remaining failures are external-network and source-map
class issues (httpbin/postman-echo abort tests, nuxt/nextjs-webpack
sourcemap assertions, fibonacci tree spawn timeouts) that lower test
parallelism doesn't address. Keeping the speedup is more valuable than
the small load reduction.
@VaguelySerious
Copy link
Copy Markdown
Member Author

Update

Three substantive fixes layered on, then one revert. Final state of the PR:

What was fixed

  1. Per-task diagnostic isolation (a115774) — setupRunTracking tracked failed-run diagnostics via two module-level mutables (trackedRuns, currentTestName) that every beforeEach reset. Under describe.concurrent, every test clobbered every other's state, so the failing test's diagnostic typically showed an unrelated sibling's workflow. Switched to Map<taskId, PerTaskState> keyed off getCurrentTest().id. Also unconditionally log [trackRun] <test> → <runId> so even when diagnostics fetching stalls past a 60s timeout, the per-test runId is still in stdout for backend correlation.
  2. writeExclusive content atomicity (2fce0bb) — fs.writeFile(path, data, { flag: 'wx' }) is atomic for the file creation (O_CREAT|O_EXCL) but not for the data write that follows. A concurrent reader could observe a half-written file (e.g. just {), which the hook-token-claim path was silently swallowing as "no claim exists" — a real correctness bug. Run-creation hit the same race and produced size=0 run JSON files surfaced in CI logs. Switched to write-then-link(2): write data to a temp file first, then atomically link it into place. POSIX link is atomic and fails with EEXIST if the target exists, preserving the exclusive-claim semantics. Readers now either see ENOENT or the fully-populated inode.
  3. readJSON SyntaxError annotation (same commit) — annotates partial-read SyntaxError with file path + size + content snippet, preserving the SyntaxError type so existing handlers like readHookTokenClaim's instanceof SyntaxError catch still work.

What was tried and reverted

  • maxConcurrency: 3 (c7060b1 → reverted in 6e264eb) — runs 3/4 at concurrency=5 and run 5 at concurrency=3 all landed on exactly 15 e2e failures. The remaining flakes don't respond to lower test parallelism, so the cap traded speedup for nothing.

What's left (out of scope for this PR)

  • Sourcemap assertion failures on nuxt and nextjs-webpack: expect(stack).not.toContain('99_e2e.ts') fires because hasStepSourceMaps() reports false but the stack does contain the .ts filename. Pre-existing test/runtime mismatch — independent of concurrency, just hits more often now that more workflows run per CI invocation. Needs separate investigation into the source-map detection logic.
  • External-network flakes on abort tests (abortFetchInFlightWorkflow, abortFetchUncaughtWorkflow, etc.): httpbin/postman-echo delay endpoints intermittently return early from GH Actions runners. [tests] Fix abort-fetch e2e flake #2081 added a fallback URL pair; under heavier concurrent load both upstreams flake. The proper fix is a per-workbench /api/delay/:n route.
  • Fibonacci tree spawn timeouts on Vercel Prod: fibonacciWorkflow with fib(6) spawns a tree of child runs; under concurrent load this saturates the workflow scheduler past the test's 180s budget. Could be addressed with a smaller fib(N), a longer budget, or marking that single test .sequential.

Verdict

The actual concurrency-introduced isolation/correctness bugs are fixed. Concurrency speedup holds (~3× job wall-clock; ~4–5× pure vitest run). The remaining failures are pre-existing issues that the concurrency change has made more visible but doesn't itself cause. Happy to keep this draft until those classes are tackled, or to merge with a green CI rerun depending on appetite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant