Skip to content

fix(core): make @opentelemetry/api dynamic import opaque to bundlers#1947

Draft
VaguelySerious wants to merge 1 commit intomainfrom
peter/fix-otel-opaque-import
Draft

fix(core): make @opentelemetry/api dynamic import opaque to bundlers#1947
VaguelySerious wants to merge 1 commit intomainfrom
peter/fix-otel-opaque-import

Conversation

@VaguelySerious
Copy link
Copy Markdown
Member

Summary

`@opentelemetry/api` is declared as an optional peer dependency on `@workflow/core` and loaded via:

```ts
try {
return await import('@opentelemetry/api');
} catch {
runtimeLogger.info('OpenTelemetry not available, tracing will be disabled');
return null;
}
```

Bundlers that statically follow `import('…')` strings reject the unresolvable specifier when the consumer hasn't installed the peer. SvelteKit's Rollup pipeline turns this into a fatal build error:

```
[vite]: Rollup failed to resolve import "@opentelemetry/api" from
"src/routes/.well-known/workflow/v1/flow/__step_registrations.js"
```

(Reproduced cleanly against `workflow-tarballs-n5b4yau0p`. Same error on the SvelteKit example in `workflow-examples`.)

Fix

Construct the specifier at runtime so static analyzers can't follow it — the same pattern `get-world-lazy.ts` uses for `./world.js`:

```ts
const specifier = ['@opentelemetry', 'api'].join('/');
return (await import(specifier)) as typeof api;
```

Runtime behavior is unchanged: present at runtime → loaded, absent → caught and tracing is disabled.

Why other bundlers haven't tripped on this

Next.js / Turbopack / esbuild (Nitro, Astro, Hono, Nuxt) currently tolerate the unresolvable specifier — either they downgrade unresolved `import()` to a runtime warning, or some transitive (`ai`, `@vercel/otel`) installs `@opentelemetry/api` so the resolution actually succeeds. SvelteKit's Rollup config is the strict case.

Relying on transitive resolution to satisfy the optional peer is brittle, so making the import opaque is the proper fix.

Test plan

  • `pnpm --filter @workflow/core build` (clean)
  • `pnpm --filter @workflow/core vitest run --exclude '/e2e/'` (941 pass)
  • Re-test SvelteKit + Astro examples in `workflow-examples` against the resulting tarball
  • CI green

🤖 Generated with Claude Code

`@opentelemetry/api` is an optional peer dependency loaded via a
try/catch'd `await import('@opentelemetry/api')`. Bundlers that
statically follow `import('…')` strings reject it as unresolvable when
the consumer hasn't installed it — SvelteKit's Rollup pipeline turns
this into a fatal build error:

  [vite]: Rollup failed to resolve import "@opentelemetry/api" from
  "src/routes/.well-known/workflow/v1/flow/__step_registrations.js"

Construct the specifier at runtime so the static analyzer can't resolve
it. The `globalThis`-cached symbol pattern used by `get-world-lazy.ts`
works for the same reason. Runtime semantics are unchanged: present →
loaded, absent → caught and tracing disabled.

Other build systems (Next.js, Nitro, Astro, Hono, Nuxt) tolerate the
unresolvable specifier today, so they were unaffected — but the same
pattern fails for any bundler that treats unresolved static specifiers
as fatal, and depending on transitive resolution to provide the peer
is brittle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 6, 2026

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

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

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 6, 2026

🦋 Changeset detected

Latest commit: 8fcd10a

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

This PR includes changesets to release 18 packages
Name Type
@workflow/core Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/vitest Patch
@workflow/web-shared Patch
@workflow/web Patch
workflow Patch
@workflow/world-testing Patch
tarballs Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/nuxt Patch
@workflow/ai 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 6, 2026

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 1200 0 219 1419
✅ 💻 Local Development 1587 0 219 1806
✅ 📦 Local Production 1587 0 219 1806
✅ 🐘 Local Postgres 1587 0 219 1806
✅ 🪟 Windows 129 0 0 129
✅ 📋 Other 727 0 176 903
Total 6817 0 1052 7869

Details by Category

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

📋 View full workflow run

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 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.031s (-27.1% 🟢) 1.005s (~) 0.974s 10 1.00x
🐘 Postgres Express 0.046s (-20.3% 🟢) 1.011s (~) 0.965s 10 1.47x
🌐 Redis Next.js (Turbopack) 0.051s 1.005s 0.954s 10 1.63x
💻 Local Next.js (Turbopack) 0.051s 1.006s 0.954s 10 1.64x
🐘 Postgres Nitro 0.052s (-45.5% 🟢) 1.013s (-2.9%) 0.961s 10 1.65x
🐘 Postgres Next.js (Turbopack) 0.059s 1.013s 0.954s 10 1.86x
🌐 MongoDB Next.js (Turbopack) 0.099s 1.008s 0.909s 10 3.14x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 0.244s (-3.1%) 2.099s (-10.1% 🟢) 1.855s 10 1.00x
▲ Vercel Nitro 0.261s (-36.4% 🟢) 1.958s (-22.0% 🟢) 1.698s 10 1.07x
▲ 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.073s (-5.2% 🟢) 2.005s (~) 0.933s 10 1.00x
🐘 Postgres Express 1.083s (-5.6% 🟢) 2.009s (~) 0.926s 10 1.01x
🐘 Postgres Nitro 1.088s (-4.6%) 2.010s (~) 0.922s 10 1.01x
🌐 Redis Next.js (Turbopack) 1.111s 2.006s 0.895s 10 1.04x
💻 Local Next.js (Turbopack) 1.115s 2.006s 0.891s 10 1.04x
🐘 Postgres Next.js (Turbopack) 1.117s 2.009s 0.891s 10 1.04x
🌐 MongoDB Next.js (Turbopack) 1.177s 2.008s 0.831s 10 1.10x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 1.524s (-25.1% 🟢) 3.531s (-7.8% 🟢) 2.007s 10 1.00x
▲ Vercel Nitro 1.562s (-59.9% 🟢) 3.289s (-44.3% 🟢) 1.727s 10 1.02x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 10.404s (-5.1% 🟢) 11.012s (~) 0.608s 3 1.00x
🐘 Postgres Nitro 10.424s (-4.1%) 11.022s (~) 0.598s 3 1.00x
💻 Local Nitro 10.426s (-4.7%) 11.021s (~) 0.594s 3 1.00x
🌐 Redis Next.js (Turbopack) 10.663s 11.023s 0.360s 3 1.02x
💻 Local Next.js (Turbopack) 10.665s 11.022s 0.357s 3 1.03x
🐘 Postgres Next.js (Turbopack) 10.691s 11.020s 0.329s 3 1.03x
🌐 MongoDB Next.js (Turbopack) 10.754s 11.022s 0.268s 3 1.03x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 13.408s (-22.6% 🟢) 15.527s (-20.0% 🟢) 2.119s 2 1.00x
▲ Vercel Nitro 13.499s (-43.1% 🟢) 15.001s (-40.3% 🟢) 1.502s 3 1.01x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 13.468s (-7.6% 🟢) 14.019s (-6.7% 🟢) 0.551s 5 1.00x
💻 Local Nitro 13.483s (-10.5% 🟢) 14.027s (-12.5% 🟢) 0.543s 5 1.00x
🐘 Postgres Nitro 13.576s (-7.0% 🟢) 14.024s (-6.7% 🟢) 0.448s 5 1.01x
💻 Local Next.js (Turbopack) 14.065s 15.029s 0.964s 4 1.04x
🌐 Redis Next.js (Turbopack) 14.104s 15.029s 0.925s 4 1.05x
🐘 Postgres Next.js (Turbopack) 14.143s 15.019s 0.876s 4 1.05x
🌐 MongoDB Next.js (Turbopack) 14.201s 15.023s 0.822s 4 1.05x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 21.209s (-67.1% 🟢) 22.574s (-66.1% 🟢) 1.365s 3 1.00x
▲ Vercel Next.js (Turbopack) 22.011s (-58.1% 🟢) 23.577s (-56.8% 🟢) 1.566s 3 1.04x
▲ 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
💻 Local 🥇 Nitro 11.902s (-29.1% 🟢) 12.021s (-29.4% 🟢) 0.118s 8 1.00x
🐘 Postgres Nitro 11.929s (-14.6% 🟢) 12.018s (-16.0% 🟢) 0.090s 8 1.00x
🐘 Postgres Express 12.207s (-12.9% 🟢) 13.018s (-10.8% 🟢) 0.812s 7 1.03x
🌐 Redis Next.js (Turbopack) 12.918s 13.025s 0.107s 7 1.09x
💻 Local Next.js (Turbopack) 13.104s 13.882s 0.778s 7 1.10x
🐘 Postgres Next.js (Turbopack) 13.243s 14.019s 0.776s 7 1.11x
🌐 MongoDB Next.js (Turbopack) 13.282s 14.024s 0.741s 7 1.12x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 34.051s (-91.9% 🟢) 35.600s (-91.6% 🟢) 1.549s 3 1.00x
▲ Vercel Next.js (Turbopack) 34.893s (-91.1% 🟢) 37.142s (-90.6% 🟢) 2.249s 3 1.02x
▲ 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.153s (-9.6% 🟢) 2.007s (~) 0.854s 15 1.00x
🐘 Postgres Express 1.161s (-7.9% 🟢) 2.007s (~) 0.847s 15 1.01x
💻 Local Nitro 1.169s (-28.4% 🟢) 2.006s (-3.3%) 0.837s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.211s 2.007s 0.796s 15 1.05x
🌐 Redis Next.js (Turbopack) 1.238s 2.006s 0.768s 15 1.07x
💻 Local Next.js (Turbopack) 1.293s 2.006s 0.712s 15 1.12x
🌐 MongoDB Next.js (Turbopack) 2.034s 2.827s 0.793s 11 1.76x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.564s (-9.0% 🟢) 3.955s (-8.5% 🟢) 1.391s 8 1.00x
▲ Vercel Next.js (Turbopack) 2.797s (-17.7% 🟢) 4.746s (-3.8%) 1.950s 7 1.09x
▲ 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.232s (-47.8% 🟢) 2.007s (-33.3% 🟢) 0.775s 15 1.00x
🐘 Postgres Nitro 1.234s (-47.5% 🟢) 2.007s (-33.3% 🟢) 0.773s 15 1.00x
🐘 Postgres Next.js (Turbopack) 1.370s 2.007s 0.637s 15 1.11x
💻 Local Nitro 1.603s (-49.0% 🟢) 2.005s (-48.4% 🟢) 0.402s 15 1.30x
💻 Local Next.js (Turbopack) 1.950s 2.469s 0.519s 13 1.58x
🌐 Redis Next.js (Turbopack) 2.367s 3.008s 0.641s 10 1.92x
🌐 MongoDB Next.js (Turbopack) 3.569s 4.010s 0.441s 8 2.90x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.455s (-14.7% 🟢) 4.536s (-23.4% 🟢) 1.082s 7 1.00x
▲ Vercel Next.js (Turbopack) 4.760s (-33.0% 🟢) 6.794s (-23.7% 🟢) 2.034s 5 1.38x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.382s (-60.3% 🟢) 2.009s (-49.9% 🟢) 0.626s 15 1.00x
🐘 Postgres Nitro 1.383s (-60.3% 🟢) 2.008s (-49.9% 🟢) 0.625s 15 1.00x
🐘 Postgres Next.js (Turbopack) 1.677s 2.075s 0.397s 15 1.21x
🌐 Redis Next.js (Turbopack) 3.592s 4.010s 0.418s 8 2.60x
💻 Local Nitro 4.452s (-46.7% 🟢) 4.727s (-47.6% 🟢) 0.276s 7 3.22x
💻 Local Next.js (Turbopack) 5.370s 6.213s 0.844s 5 3.88x
🌐 MongoDB Next.js (Turbopack) 6.291s 7.014s 0.723s 5 4.55x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 7.248s (-18.7% 🟢) 9.096s (-17.0% 🟢) 1.848s 4 1.00x
▲ Vercel Nitro 7.440s (+111.0% 🔺) 9.168s (+65.7% 🔺) 1.728s 4 1.03x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.156s (-8.1% 🟢) 2.009s (~) 0.853s 15 1.00x
🐘 Postgres Express 1.157s (-7.9% 🟢) 2.007s (~) 0.849s 15 1.00x
🐘 Postgres Next.js (Turbopack) 1.220s 2.008s 0.788s 15 1.06x
🌐 Redis Next.js (Turbopack) 1.256s 2.006s 0.751s 15 1.09x
💻 Local Next.js (Turbopack) 1.321s 2.006s 0.685s 15 1.14x
💻 Local Nitro 1.417s (-24.0% 🟢) 2.006s (-14.3% 🟢) 0.589s 15 1.23x
🌐 MongoDB Next.js (Turbopack) 2.026s 2.674s 0.648s 12 1.75x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.522s (+2.5%) 3.759s (-9.8% 🟢) 1.237s 8 1.00x
▲ Vercel Next.js (Turbopack) 2.599s (-11.4% 🟢) 4.262s (-8.2% 🟢) 1.664s 8 1.03x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.227s (-47.6% 🟢) 2.009s (-33.3% 🟢) 0.782s 15 1.00x
🐘 Postgres Express 1.229s (-47.5% 🟢) 2.008s (-33.3% 🟢) 0.779s 15 1.00x
🐘 Postgres Next.js (Turbopack) 1.376s 2.007s 0.631s 15 1.12x
💻 Local Nitro 1.732s (-43.5% 🟢) 2.072s (-46.7% 🟢) 0.340s 15 1.41x
💻 Local Next.js (Turbopack) 2.066s 2.735s 0.669s 11 1.68x
🌐 Redis Next.js (Turbopack) 2.344s 3.008s 0.664s 10 1.91x
🌐 MongoDB Next.js (Turbopack) 3.586s 4.009s 0.423s 8 2.92x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.903s (+20.7% 🔺) 5.283s (+4.1%) 1.380s 6 1.00x
▲ Vercel Next.js (Turbopack) 5.185s (+65.0% 🔺) 6.676s (+47.6% 🔺) 1.492s 5 1.33x
▲ 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.374s (-60.5% 🟢) 2.008s (-49.9% 🟢) 0.634s 15 1.00x
🐘 Postgres Express 1.394s (-60.2% 🟢) 2.007s (-50.0% 🟢) 0.613s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.705s 2.152s 0.447s 14 1.24x
🌐 Redis Next.js (Turbopack) 3.587s 4.010s 0.423s 8 2.61x
💻 Local Nitro 5.098s (-44.2% 🟢) 5.302s (-47.1% 🟢) 0.204s 7 3.71x
💻 Local Next.js (Turbopack) 5.688s 6.349s 0.661s 6 4.14x
🌐 MongoDB Next.js (Turbopack) 6.319s 7.013s 0.694s 5 4.60x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 5.435s (-19.6% 🟢) 7.409s (-13.3% 🟢) 1.974s 5 1.00x
▲ Vercel Nitro 5.733s (+12.6% 🔺) 7.215s (+5.8% 🔺) 1.482s 5 1.05x
▲ 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 🥇 Express 0.459s (-45.3% 🟢) 1.023s (~) 0.564s 59 1.00x
💻 Local Nitro 0.472s (-51.9% 🟢) 1.003s (-8.3% 🟢) 0.532s 60 1.03x
🐘 Postgres Nitro 0.483s (-41.1% 🟢) 1.023s (+1.7%) 0.540s 59 1.05x
🌐 Redis Next.js (Turbopack) 0.610s 1.004s 0.394s 60 1.33x
🐘 Postgres Next.js (Turbopack) 0.673s 1.006s 0.334s 60 1.47x
💻 Local Next.js (Turbopack) 0.710s 1.005s 0.294s 60 1.55x
🌐 MongoDB Next.js (Turbopack) 0.725s 1.006s 0.281s 60 1.58x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 4.784s (-67.0% 🟢) 6.361s (-60.5% 🟢) 1.577s 10 1.00x
▲ Vercel Nitro 4.904s (-77.8% 🟢) 6.301s (-73.8% 🟢) 1.396s 10 1.03x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.044s (-45.9% 🟢) 1.586s (-24.5% 🟢) 0.542s 57 1.00x
🐘 Postgres Express 1.047s (-47.0% 🟢) 1.772s (-21.5% 🟢) 0.725s 51 1.00x
💻 Local Nitro 1.133s (-62.7% 🟢) 2.005s (-46.6% 🟢) 0.872s 45 1.09x
🌐 Redis Next.js (Turbopack) 1.484s 2.006s 0.522s 45 1.42x
🐘 Postgres Next.js (Turbopack) 1.623s 2.008s 0.385s 45 1.55x
💻 Local Next.js (Turbopack) 1.765s 2.006s 0.241s 45 1.69x
🌐 MongoDB Next.js (Turbopack) 1.817s 2.007s 0.190s 45 1.74x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 14.165s (-71.6% 🟢) 16.255s (-68.6% 🟢) 2.090s 6 1.00x
▲ Vercel Nitro 14.305s (-63.8% 🟢) 15.937s (-61.4% 🟢) 1.632s 6 1.01x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 2.103s (-48.8% 🟢) 2.639s (-42.7% 🟢) 0.537s 46 1.00x
🐘 Postgres Express 2.157s (-45.9% 🟢) 2.781s (-36.3% 🟢) 0.624s 44 1.03x
💻 Local Nitro 2.539s (-72.7% 🟢) 3.007s (-70.0% 🟢) 0.468s 40 1.21x
🌐 Redis Next.js (Turbopack) 2.969s 3.135s 0.166s 39 1.41x
🐘 Postgres Next.js (Turbopack) 3.161s 4.008s 0.848s 30 1.50x
💻 Local Next.js (Turbopack) 3.773s 4.008s 0.236s 30 1.79x
🌐 MongoDB Next.js (Turbopack) 4.139s 5.012s 0.873s 24 1.97x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 42.600s (-56.0% 🟢) 44.528s (-54.8% 🟢) 1.929s 3 1.00x
▲ Vercel Next.js (Turbopack) 43.701s (-59.2% 🟢) 46.184s (-57.6% 🟢) 2.484s 3 1.03x
▲ 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.189s (-33.1% 🟢) 1.006s (~) 0.817s 60 1.00x
🐘 Postgres Express 0.191s (-32.5% 🟢) 1.006s (~) 0.815s 60 1.01x
🐘 Postgres Next.js (Turbopack) 0.232s 1.006s 0.774s 60 1.23x
🌐 Redis Next.js (Turbopack) 0.241s 1.004s 0.763s 60 1.27x
💻 Local Nitro 0.428s (-29.3% 🟢) 1.004s (-1.8%) 0.576s 60 2.26x
💻 Local Next.js (Turbopack) 0.544s 1.005s 0.460s 60 2.87x
🌐 MongoDB Next.js (Turbopack) 1.043s 1.882s 0.838s 32 5.51x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.520s (+51.7% 🔺) 4.002s (+19.4% 🔺) 1.482s 15 1.00x
▲ Vercel Next.js (Turbopack) 2.764s (+36.6% 🔺) 4.421s (+16.5% 🔺) 1.657s 14 1.10x
▲ 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 🥇 Express 0.320s (-37.3% 🟢) 1.006s (~) 0.686s 90 1.00x
🐘 Postgres Nitro 0.328s (-34.0% 🟢) 1.006s (~) 0.678s 90 1.02x
🌐 Redis Next.js (Turbopack) 0.407s 1.004s 0.597s 90 1.27x
🐘 Postgres Next.js (Turbopack) 0.440s 1.006s 0.566s 90 1.38x
💻 Local Nitro 2.083s (-17.9% 🟢) 2.654s (-11.8% 🟢) 0.571s 34 6.51x
💻 Local Next.js (Turbopack) 2.244s 3.009s 0.765s 30 7.02x
🌐 MongoDB Next.js (Turbopack) 2.612s 3.007s 0.396s 30 8.16x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 7.689s (+138.4% 🔺) 9.317s (+93.2% 🔺) 1.628s 10 1.00x
▲ Vercel Next.js (Turbopack) 8.886s (+151.3% 🔺) 10.812s (+108.2% 🔺) 1.926s 9 1.16x
▲ 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.654s (-17.2% 🟢) 1.006s (~) 0.352s 120 1.00x
🐘 Postgres Express 0.660s (-19.4% 🟢) 1.006s (-1.1%) 0.346s 120 1.01x
🌐 Redis Next.js (Turbopack) 0.744s 1.004s 0.260s 120 1.14x
🐘 Postgres Next.js (Turbopack) 0.924s 1.219s 0.294s 99 1.41x
🌐 MongoDB Next.js (Turbopack) 5.396s 6.013s 0.618s 20 8.25x
💻 Local Nitro 8.955s (-20.0% 🟢) 9.560s (-18.0% 🟢) 0.606s 13 13.68x
💻 Local Next.js (Turbopack) 11.573s 12.230s 0.657s 10 17.69x
💻 Local Express ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 23.627s (+128.8% 🔺) 25.405s (+106.8% 🔺) 1.778s 5 1.00x
▲ Vercel Nitro 24.638s (+219.0% 🔺) 26.403s (+180.9% 🔺) 1.765s 5 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
💻 Local 🥇 Nitro 1.119s (+423.5% 🔺) 2.005s (+99.6% 🔺) 0.009s (-24.0% 🟢) 2.016s (+97.9% 🔺) 0.898s 10 1.00x
🐘 Postgres Nitro 1.139s (+455.5% 🔺) 2.000s (+100.1% 🔺) 0.001s (-13.3% 🟢) 2.010s (+98.8% 🔺) 0.871s 10 1.02x
🐘 Postgres Express 1.148s (+459.7% 🔺) 1.996s (+99.8% 🔺) 0.002s (-6.3% 🟢) 2.010s (+98.8% 🔺) 0.862s 10 1.03x
💻 Local Next.js (Turbopack) 1.182s 2.004s 0.012s 2.020s 0.839s 10 1.06x
🐘 Postgres Next.js (Turbopack) 1.191s 2.002s 0.001s 2.011s 0.820s 10 1.06x
💻 Local Express ⚠️ missing - - - - -
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.197s (-42.7% 🟢) 3.054s (-42.1% 🟢) 2.076s (+179.8% 🔺) 5.474s (-15.6% 🟢) 3.277s 10 1.00x
▲ Vercel Next.js (Turbopack) 2.295s (-66.5% 🟢) 3.222s (-62.8% 🟢) 1.965s (+211.0% 🔺) 5.659s (-42.2% 🟢) 3.364s 10 1.04x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.507s (+141.4% 🔺) 2.002s (+98.9% 🔺) 0.004s (-5.7% 🟢) 2.025s (+98.1% 🔺) 0.518s 30 1.00x
🐘 Postgres Express 1.513s (+140.1% 🔺) 2.001s (+98.8% 🔺) 0.004s (+4.4%) 2.027s (+98.1% 🔺) 0.514s 30 1.00x
🐘 Postgres Next.js (Turbopack) 1.670s 2.011s 0.004s 2.026s 0.356s 30 1.11x
💻 Local Nitro 1.677s (+100.0% 🔺) 2.009s (+98.6% 🔺) 0.010s (+3.3%) 2.200s (+97.2% 🔺) 0.523s 28 1.11x
💻 Local Next.js (Turbopack) 1.681s 2.011s 0.010s 2.024s 0.342s 30 1.12x
💻 Local Express ⚠️ missing - - - - -
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 5.842s (-65.5% 🟢) 7.097s (-61.1% 🟢) 0.302s (+43.0% 🔺) 7.901s (-58.3% 🟢) 2.059s 8 1.00x
▲ Vercel Nitro 5.857s (-80.1% 🟢) 6.862s (-77.7% 🟢) 0.217s (+94.1% 🔺) 7.475s (-76.5% 🟢) 1.618s 9 1.00x
▲ 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.679s (-29.9% 🟢) 1.046s (-16.1% 🟢) 0.000s (-15.8% 🟢) 1.060s (-15.7% 🟢) 0.381s 57 1.00x
🐘 Postgres Express 0.682s (-29.0% 🟢) 1.010s (-20.9% 🟢) 0.000s (-20.7% 🟢) 1.043s (-20.2% 🟢) 0.361s 58 1.00x
🐘 Postgres Next.js (Turbopack) 0.812s 1.072s 0.000s 1.085s 0.273s 56 1.20x
💻 Local Nitro 1.315s (+7.6% 🔺) 2.014s (~) 0.000s (+66.7% 🔺) 2.016s (~) 0.701s 30 1.94x
💻 Local Next.js (Turbopack) 1.448s 2.014s 0.000s 2.017s 0.569s 30 2.13x
💻 Local Express ⚠️ missing - - - - -
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 3.732s (-63.3% 🟢) 4.741s (-58.8% 🟢) 0.000s (+Infinity% 🔺) 5.158s (-57.2% 🟢) 1.426s 12 1.00x
▲ Vercel Nitro 3.734s (+22.4% 🔺) 4.682s (+6.6% 🔺) 0.000s (+225.0% 🔺) 5.077s (+5.6% 🔺) 1.344s 12 1.00x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

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

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.293s (-27.0% 🟢) 2.065s (-5.2% 🟢) 0.000s (+Infinity% 🔺) 2.089s (-5.0%) 0.796s 29 1.00x
🐘 Postgres Nitro 1.352s (-24.5% 🟢) 2.098s (-2.0%) 0.000s (+286.2% 🔺) 2.113s (-2.8%) 0.761s 29 1.05x
🐘 Postgres Next.js (Turbopack) 1.687s 2.225s 0.000s 2.235s 0.547s 27 1.30x
💻 Local Next.js (Turbopack) 2.602s 3.129s 0.001s 3.133s 0.531s 20 2.01x
💻 Local Nitro 3.037s (-10.3% 🟢) 3.732s (-7.4% 🟢) 0.000s (-77.9% 🟢) 3.734s (-7.5% 🟢) 0.697s 17 2.35x
💻 Local Express ⚠️ missing - - - - -
🌐 MongoDB Next.js (Turbopack) ⚠️ missing - - - - -
🌐 Redis Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.601s (+36.8% 🔺) 6.956s (+29.4% 🔺) 0.000s (-100.0% 🟢) 7.307s (+26.1% 🔺) 1.706s 9 1.00x
▲ Vercel Next.js (Turbopack) 6.401s (+14.0% 🔺) 7.559s (+8.3% 🔺) 0.000s (~) 8.009s (+6.2% 🔺) 1.609s 8 1.14x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Nitro 19/21
🐘 Postgres Nitro 12/21
▲ Vercel Nitro 11/21
Fastest World by Framework

Winner determined by most benchmark wins

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

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)

📋 View full workflow run


Some benchmark jobs failed:

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

Check the workflow run for details.

const specifier = ['@opentelemetry', 'api'].join('/');
try {
return await import('@opentelemetry/api');
return (await import(specifier)) as typeof api;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we mark this as external instead?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants