Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

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" + '
Split tarball hosting out of docs into its own project by VaguelySerious · Pull Request #1893 · vercel/workflow · GitHub
Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

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('^' + ".*" + ' Split tarball hosting out of docs into its own project by VaguelySerious · Pull Request #1893 · vercel/workflow · GitHub
Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

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('^' + ".*" + ' Split tarball hosting out of docs into its own project by VaguelySerious · Pull Request #1893 · vercel/workflow · GitHub
Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

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" + ' Split tarball hosting out of docs into its own project by VaguelySerious · Pull Request #1893 · vercel/workflow · GitHub
Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

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('^' + ".*" + ' Split tarball hosting out of docs into its own project by VaguelySerious · Pull Request #1893 · vercel/workflow · GitHub
Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

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('^' + ".*" + ' Split tarball hosting out of docs into its own project by VaguelySerious · Pull Request #1893 · vercel/workflow · GitHub
Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

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); } })(); })(); Split tarball hosting out of docs into its own project by VaguelySerious · Pull Request #1893 · vercel/workflow · GitHub
Skip to content

Split tarball hosting out of docs into its own project - #1893

Merged
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs
May 4, 2026
Merged

Split tarball hosting out of docs into its own project#1893
VaguelySerious merged 5 commits into
mainfrom
peter/split-tarballs-from-docs

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

The docs project was incidentally hosting preview tarballs because of a prebuild step that ran scripts/pack.ts and dumped *.tgz into docs/public/. This PR moves all of that into a new top-level tarballs/ workspace package that deploys as its own static Vercel project.

Follow-up (manual, not in this PR)

  • Create the workflow-tarballs Vercel project linked to tarballs/ (no framework preset; outputDirectory: public; install command runs at the repo root for the workspace). The new CI workflow's project-slug: workflow-tarballs depends on this.
  • Once the new deployment URL is live, update the pre-release-testing snippet that points at https://workflow-docs-…vercel.sh/<pkg>.tgz to use the new host.

The docs project was incidentally hosting preview tarballs because of a
prebuild step that ran scripts/pack.ts and dumped *.tgz into
docs/public/. Move all of that — pack script, smoke checks, gitignore
entries, the .tgz proxy matcher exception — into a new top-level
`tarballs/` workspace package that deploys as its own static Vercel
project (framework: null, outputDirectory: public).
Also fix a long-standing oddity in pack.ts where restoring the
package.json after `pnpm pack` dropped the trailing newline because
the original was rebuilt with JSON.stringify rather than the source
bytes. The new version stores the raw original content and writes it
back verbatim.
Adds .github/workflows/tarballs-checks.yml that waits for the
workflow-tarballs Vercel project and runs the new smoke script.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-botBot commented May 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 76406b5

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

This PR includes changesets to release 0 packages

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

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 May 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented May 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production10110671078
✅ 💻 Local Development10900861176
✅ 📦 Local Production10900861176
✅ 🐘 Local Postgres10900861176
✅ 🪟 Windows980098
✅ 📋 Other276018294
Total465503434998

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro9107
✅ example9107
✅ express9107
✅ fastify9107
✅ hono9107
✅ nextjs-turbopack9602
✅ nextjs-webpack9602
✅ nitro9107
✅ nuxt9107
✅ sveltekit9107
✅ vite9107
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable9206
✅ express-stable9206
✅ fastify-stable9206
✅ hono-stable9206
✅ nextjs-turbopack-canary79019
✅ nextjs-turbopack-stable9800
✅ nextjs-webpack-canary79019
✅ nextjs-webpack-stable9800
✅ nitro-stable9206
✅ nuxt-stable9206
✅ sveltekit-stable9206
✅ vite-stable9206
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack9800
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable9206
✅ e2e-local-postgres-nest-stable9206
✅ e2e-local-prod-nest-stable9206

📋 View full workflow run

@github-actions

github-actionsBot commented May 2, 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🥇 Nitro0.041s (-4.2%)1.005s (~)0.964s101.00x
💻 LocalExpress0.044s (~)1.006s (~)0.961s101.07x
🐘 PostgresExpress0.061s (+5.0%)1.011s (~)0.950s101.47x
🐘 PostgresNitro0.062s (-35.1% 🟢)1.010s (-3.2%)0.948s101.50x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express0.209s (-11.1% 🟢)1.790s (-16.2% 🟢)1.581s101.00x
▲ VercelNitro0.245s (-40.1% 🟢)2.381s (-5.1% 🟢)2.136s101.17x
▲ VercelNext.js (Turbopack)0.493s (+96.2% 🔺)2.123s (-9.0% 🟢)1.630s102.36x

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

workflow with 1 step

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
💻 Local🥇 Nitro1.130s (~)2.006s (~)0.876s101.00x
💻 LocalExpress1.133s (+0.7%)2.006s (~)0.873s101.00x
🐘 PostgresExpress1.150s (~)2.010s (~)0.860s101.02x
🐘 PostgresNitro1.157s (+1.5%)2.013s (~)0.856s101.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.881s (-51.7% 🟢)3.929s (-33.5% 🟢)2.048s101.00x
▲ VercelNext.js (Turbopack)1.936s (-4.9%)4.539s (+18.5% 🔺)2.603s101.03x
▲ VercelExpress2.002s (+6.8% 🔺)3.942s (+3.5%)1.940s101.06x

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

workflow with 10 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro10.896s (~)11.027s (~)0.131s31.00x
🐘 PostgresExpress10.925s (~)11.022s (~)0.096s31.00x
💻 LocalNitro10.926s (~)11.023s (~)0.097s31.00x
💻 LocalExpress10.945s (~)11.026s (~)0.081s31.00x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express17.273s (+1.7%)23.617s (+18.0% 🔺)6.344s21.00x
▲ VercelNitro17.620s (-25.8% 🟢)19.602s (-22.0% 🟢)1.982s21.02x
▲ VercelNext.js (Turbopack)18.267s (+5.5% 🔺)20.644s (+6.4% 🔺)2.377s21.06x

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

workflow with 25 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.608s (~)15.024s (~)0.416s41.00x
🐘 PostgresExpress14.697s (+0.8%)15.023s (~)0.326s41.01x
💻 LocalNitro14.974s (-0.6%)15.030s (-6.2% 🟢)0.056s41.03x
💻 LocalExpress15.085s (+0.8%)16.037s (+6.7% 🔺)0.952s41.03x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro34.069s (-47.1% 🟢)36.025s (-45.9% 🟢)1.956s21.00x
▲ VercelExpress34.371s (-31.7% 🟢)36.460s (-30.6% 🟢)2.089s21.01x
▲ VercelNext.js (Turbopack)35.372s (-32.7% 🟢)37.834s (-30.7% 🟢)2.462s21.04x

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

workflow with 50 sequential steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro14.085s (+0.8%)14.880s (+4.0%)0.795s71.00x
🐘 PostgresExpress14.385s (+2.7%)15.022s (+2.9%)0.637s61.02x
💻 LocalNitro16.368s (-2.5%)17.029s (~)0.661s61.16x
💻 LocalExpress17.004s (+2.4%)17.533s (+2.9%)0.529s61.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express58.020s (-52.1% 🟢)62.091s (-49.8% 🟢)4.071s21.00x
▲ VercelNitro62.876s (-85.1% 🟢)66.238s (-84.4% 🟢)3.362s21.08x
▲ VercelNext.js (Turbopack)64.767s (-83.5% 🟢)66.550s (-83.2% 🟢)1.782s21.12x

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

Promise.all with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express1.268s (+0.6%)2.010s (~)0.741s151.00x
🐘 PostgresNitro1.269s (~)2.011s (~)0.742s151.00x
💻 LocalNitro1.504s (-7.8% 🟢)2.006s (-3.3%)0.501s151.19x
💻 LocalExpress1.506s (+1.2%)2.006s (~)0.500s151.19x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.473s (-27.2% 🟢)4.591s (-6.9% 🟢)2.118s71.00x
▲ VercelExpress2.667s (-6.8% 🟢)4.775s (+3.3%)2.109s71.08x
▲ VercelNitro2.780s (-1.3%)4.900s (+13.4% 🔺)2.120s71.12x

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

Promise.all with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.334s (-0.7%)3.009s (~)0.675s101.00x
🐘 PostgresExpress2.370s (~)3.011s (~)0.641s101.02x
💻 LocalExpress2.917s (-1.2%)3.453s (~)0.537s91.25x
💻 LocalNitro3.010s (-4.2%)3.342s (-14.0% 🟢)0.331s91.29x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.475s (-38.9% 🟢)4.113s (-30.5% 🟢)1.638s81.00x
▲ VercelExpress2.801s (-22.6% 🟢)4.522s (-11.5% 🟢)1.721s71.13x
▲ VercelNext.js (Turbopack)2.824s (-60.2% 🟢)5.420s (-39.1% 🟢)2.596s61.14x

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

Promise.all with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express3.492s (~)4.011s (~)0.519s81.00x
🐘 PostgresNitro3.493s (~)4.009s (~)0.516s81.00x
💻 LocalNitro7.258s (-13.1% 🟢)8.019s (-11.1% 🟢)0.761s42.08x
💻 LocalExpress8.421s (+1.0%)9.022s (~)0.601s42.41x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro3.398s (-3.6%)6.441s (+16.4% 🔺)3.043s51.00x
▲ VercelExpress3.748s (-11.6% 🟢)5.714s (-6.7% 🟢)1.966s61.10x
▲ VercelNext.js (Turbopack)3.942s (-55.8% 🟢)5.897s (-46.2% 🟢)1.955s61.16x

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

Promise.race with 10 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.252s (~)2.008s (~)0.756s151.00x
🐘 PostgresExpress1.260s (~)2.009s (~)0.749s151.01x
💻 LocalNitro1.518s (-18.6% 🟢)2.005s (-14.3% 🟢)0.487s151.21x
💻 LocalExpress1.586s (-16.2% 🟢)2.006s (-15.1% 🟢)0.420s151.27x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)2.257s (-23.0% 🟢)4.484s (-3.4%)2.226s71.00x
▲ VercelExpress2.442s (-5.4% 🟢)4.439s (+2.1%)1.997s71.08x
▲ VercelNitro3.165s (+28.7% 🔺)5.352s (+28.4% 🔺)2.187s61.40x

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

Promise.race with 25 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro2.342s (~)3.011s (~)0.668s101.00x
🐘 PostgresExpress2.371s (+1.3%)3.011s (~)0.639s101.01x
💻 LocalNitro3.010s (-1.8%)3.454s (-11.1% 🟢)0.444s91.29x
💻 LocalExpress3.117s (~)4.011s (+6.6% 🔺)0.894s81.33x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.335s (-26.9% 🟢)4.537s (-5.3% 🟢)2.202s71.00x
▲ VercelNitro2.428s (-24.9% 🟢)4.463s (-12.1% 🟢)2.035s71.04x
▲ VercelNext.js (Turbopack)2.897s (-7.8% 🟢)15.296s (+238.3% 🔺)12.399s21.24x

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

Promise.race with 50 concurrent steps

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro3.488s (~)4.011s (~)0.523s81.00x
🐘 PostgresExpress3.510s (~)4.012s (~)0.502s81.01x
💻 LocalNitro8.106s (-11.4% 🟢)8.520s (-15.0% 🟢)0.414s42.32x
💻 LocalExpress9.358s (+6.3% 🔺)10.024s (+8.1% 🔺)0.667s32.68x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro2.776s (-45.5% 🟢)13.696s (+100.9% 🔺)10.920s31.00x
▲ VercelExpress2.839s (-55.8% 🟢)7.862s (-3.9%)5.023s51.02x
▲ VercelNext.js (Turbopack)3.757s (-44.4% 🟢)8.109s (-5.1% 🟢)4.352s51.35x

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

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.837s (+2.1%)1.023s (+1.7%)0.186s591.00x
🐘 PostgresExpress0.852s (+1.5%)1.006s (-1.6%)0.155s601.02x
💻 LocalNitro1.005s (+2.4%)1.468s (+34.2% 🔺)0.464s411.20x
💻 LocalExpress1.010s (+2.7%)1.584s (+47.3% 🔺)0.574s381.21x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express8.842s (-53.5% 🟢)14.677s (-31.2% 🟢)5.836s51.00x
▲ VercelNitro9.488s (-57.0% 🟢)15.095s (-37.2% 🟢)5.607s41.07x
▲ VercelNext.js (Turbopack)9.553s (-34.1% 🟢)14.404s (-10.4% 🟢)4.851s51.08x

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

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.965s (+1.9%)2.204s (+4.9%)0.239s411.00x
🐘 PostgresExpress2.041s (+3.3%)2.798s (+23.9% 🔺)0.757s331.04x
💻 LocalNitro3.025s (~)3.689s (-1.9%)0.664s251.54x
💻 LocalExpress3.052s (+1.2%)4.011s (+11.9% 🔺)0.959s231.55x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express28.450s (-17.6% 🟢)34.648s (-5.9% 🟢)6.199s31.00x
▲ VercelNitro29.355s (-25.7% 🟢)39.049s (-5.4% 🟢)9.694s31.03x
▲ VercelNext.js (Turbopack)32.340s (-35.1% 🟢)38.077s (-26.4% 🟢)5.737s31.14x

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

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro4.015s (-2.1%)4.565s (-0.8%)0.550s271.00x
🐘 PostgresExpress4.143s (+3.8%)4.972s (+13.8% 🔺)0.829s251.03x
💻 LocalNitro8.989s (-3.3%)9.556s (-4.6%)0.567s132.24x
💻 LocalExpress9.172s (~)9.788s (-2.3%)0.616s132.28x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express73.357s (-43.6% 🟢)76.108s (-42.4% 🟢)2.751s21.00x
▲ VercelNitro78.244s (-19.3% 🟢)81.122s (-17.6% 🟢)2.878s21.07x
▲ VercelNext.js (Turbopack)78.383s (-26.8% 🟢)82.499s (-24.3% 🟢)4.116s21.07x

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

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.288s (+1.7%)1.008s (~)0.720s601.00x
🐘 PostgresExpress0.299s (+6.0% 🔺)1.008s (~)0.708s601.04x
💻 LocalNitro0.579s (-4.2%)1.004s (-1.7%)0.425s602.01x
💻 LocalExpress0.605s (+7.9% 🔺)1.005s (~)0.400s602.10x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)1.775s (-12.2% 🟢)10.347s (+172.8% 🔺)8.572s61.00x
▲ VercelNitro2.524s (+52.0% 🔺)5.079s (+51.6% 🔺)2.555s121.42x
▲ VercelExpress2.620s (+34.1% 🔺)6.694s (+84.0% 🔺)4.074s101.48x

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

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.501s (+0.9%)1.007s (~)0.506s901.00x
🐘 PostgresExpress0.512s (~)1.006s (~)0.494s901.02x
💻 LocalNitro2.350s (-7.4% 🟢)3.009s (~)0.659s304.69x
💻 LocalExpress2.513s (~)3.009s (~)0.496s305.02x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express2.995s (-1.7%)8.494s (+76.7% 🔺)5.499s111.00x
▲ VercelNitro3.818s (+18.4% 🔺)11.255s (+133.4% 🔺)7.437s81.27x
▲ VercelNext.js (Turbopack)3.955s (+11.9% 🔺)7.737s (+49.0% 🔺)3.783s121.32x

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

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.829s (+4.9%)1.026s (+1.9%)0.198s1171.00x
🐘 PostgresExpress0.838s (+2.4%)1.010s (-0.7%)0.172s1191.01x
💻 LocalNitro10.358s (-7.4% 🟢)10.936s (-6.2% 🟢)0.578s1112.50x
💻 LocalExpress11.215s (~)11.664s (-2.3%)0.449s1113.53x
💻 LocalNext.js (Turbopack)⚠️missing----
🐘 PostgresNext.js (Turbopack)⚠️missing----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Next.js (Turbopack)6.108s (-40.9% 🟢)11.381s (-7.4% 🟢)5.273s111.00x
▲ VercelNitro6.414s (-16.9% 🟢)13.562s (+44.3% 🔺)7.148s91.05x
▲ VercelExpress6.912s (-6.9% 🟢)13.400s (+45.0% 🔺)6.488s91.13x

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

Stream Benchmarks(includes TTFB metrics)
workflow with stream

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro0.206s (+0.6%)0.996s (~)0.001s (-13.3% 🟢)1.011s (~)0.804s101.00x
🐘 PostgresExpress0.207s (+0.8%)1.000s (~)0.002s (-6.3% 🟢)1.010s (~)0.803s101.00x
💻 LocalNitro0.208s (-2.7%)1.004s (~)0.010s (-21.6% 🟢)1.016s (~)0.808s101.01x
💻 LocalExpress0.208s (+4.7%)1.004s (~)0.012s (-0.8%)1.018s (~)0.810s101.01x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro1.908s (-50.2% 🟢)4.269s (-19.1% 🟢)1.458s (+96.4% 🔺)6.262s (-3.4%)4.354s101.00x
▲ VercelNext.js (Turbopack)1.985s (-71.0% 🟢)3.514s (-59.4% 🟢)3.375s (+434.1% 🔺)7.519s (-23.2% 🟢)5.535s101.04x
▲ VercelExpress2.026s (-19.1% 🟢)3.489s (-14.7% 🟢)2.595s (+170.1% 🔺)6.991s (+25.0% 🔺)4.965s101.06x

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

stream pipeline with 5 transform steps (1MB)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.622s (-1.3%)1.007s (~)0.004s (+4.0%)1.023s (~)0.401s591.00x
🐘 PostgresNitro0.634s (+1.6%)1.006s (~)0.005s (+20.1% 🔺)1.025s (~)0.391s591.02x
💻 LocalNitro0.775s (-7.6% 🟢)1.013s (~)0.009s (~)1.024s (-8.2% 🟢)0.249s591.25x
💻 LocalExpress0.855s (+12.9% 🔺)1.012s (-1.6%)0.010s (+5.6% 🔺)1.117s (+7.4% 🔺)0.262s541.37x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express4.240s (-34.8% 🟢)12.843s (+60.3% 🔺)0.255s (-37.7% 🟢)13.795s (+56.1% 🔺)9.555s51.00x
▲ VercelNitro4.291s (-85.4% 🟢)8.460s (-72.5% 🟢)0.268s (+138.9% 🔺)9.437s (-70.3% 🟢)5.145s71.01x
▲ VercelNext.js (Turbopack)5.348s (-68.4% 🟢)11.186s (-38.7% 🟢)0.768s (+263.4% 🔺)12.787s (-32.5% 🟢)7.439s51.26x

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

10 parallel streams (1MB each)

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Express0.961s (~)1.172s (-8.3% 🟢)0.000s (-54.9% 🟢)1.190s (-8.9% 🟢)0.229s511.00x
🐘 PostgresNitro0.990s (+2.2%)1.293s (+3.6%)0.000s (+53.2% 🔺)1.306s (+3.9%)0.316s471.03x
💻 LocalNitro1.237s (+1.2%)2.021s (~)0.000s (+300.0% 🔺)2.023s (~)0.786s301.29x
💻 LocalExpress1.268s (+3.6%)2.023s (~)0.000s (-30.0% 🟢)2.025s (~)0.757s301.32x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Express3.261s (-12.8% 🟢)14.309s (+180.4% 🔺)0.000s (-100.0% 🟢)15.043s (+172.0% 🔺)11.782s51.00x
▲ VercelNext.js (Turbopack)3.464s (-66.0% 🟢)7.312s (-36.5% 🟢)0.000s (NaN%)9.153s (-24.0% 🟢)5.688s71.06x
▲ VercelNitro3.996s (+31.0% 🔺)6.959s (+58.4% 🔺)0.000s (+85.7% 🔺)8.817s (+83.4% 🔺)4.822s71.23x

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

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

💻 Local Development

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
🐘 Postgres🥇 Nitro1.776s (-0.9%)2.140s (~)0.000s (-100.0% 🟢)2.154s (-1.0%)0.377s281.00x
🐘 PostgresExpress1.878s (+6.0% 🔺)2.177s (~)0.000s (NaN%)2.188s (~)0.310s281.06x
💻 LocalNitro3.468s (+2.4%)4.035s (~)0.001s (+62.5% 🔺)4.038s (~)0.570s151.95x
💻 LocalExpress3.749s (+8.1% 🔺)4.168s (+3.3%)0.001s (-8.3% 🟢)4.170s (+3.3%)0.421s152.11x
💻 LocalNext.js (Turbopack)⚠️missing-----
🐘 PostgresNext.js (Turbopack)⚠️missing-----

▲ Production (Vercel)

WorldFrameworkWorkflow TimeTTFBSlurpWall TimeOverheadSamplesvs Fastest
▲ Vercel🥇 Nitro4.338s (+6.0% 🔺)12.974s (+141.4% 🔺)0.000s (-100.0% 🟢)13.545s (+133.8% 🔺)9.207s51.00x
▲ VercelExpress4.413s (-3.8%)10.430s (+73.2% 🔺)0.000s (NaN%)11.167s (+72.9% 🔺)6.753s61.02x
▲ VercelNext.js (Turbopack)4.639s (-17.4% 🟢)9.135s (+30.8% 🔺)0.000s (-100.0% 🟢)10.832s (+43.7% 🔺)6.194s61.07x

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

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World🥇 Fastest FrameworkWins
💻 LocalNitro20/21
🐘 PostgresNitro15/21
▲ VercelExpress10/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework🥇 Fastest WorldWins
Express🐘 Postgres17/21
Next.js (Turbopack)▲ Vercel21/21
Nitro🐘 Postgres17/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

@vercelvercelBot 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.

Additional Suggestion:

PreviewBadge constructs tarball URLs pointing to the docs deployment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.

Fix on Vercel

…ment, but tarballs are no longer served from docs after being split into a separate project, causing 404s for install commands.
This commit fixes the issue reported at docs/app/[lang]/(home)/components/preview-badge.tsx:70
**Bug explanation:**
The PR (commit 98d97cd) split tarball hosting out of the docs project into a new top-level `tarballs/` workspace that deploys as its own Vercel project (`workflow-tarballs`). This involved:
1. Moving `docs/scripts/pack.ts` → `tarballs/scripts/pack.ts`
2. Removing the `prebuild` script from `docs/package.json` (which previously ran `pack.ts` and placed `.tgz` files into `docs/public/`)
3. Removing the `.tgz` exclusion from the docs proxy middleware matcher
4. Creating `tarballs/vercel.json` for the new static Vercel project
However, the `PreviewBadge` component at `docs/app/[lang]/(home)/components/preview-badge.tsx` was NOT updated. It still constructs tarball URLs using `deploymentUrl` which comes from the docs project's `VERCEL_URL`:
```
const baseUrl = deploymentUrl.replace(//$/, '');
const installCmd = `pnpm i ${baseUrl}/workflow.tgz`;
```
Since the docs deployment no longer serves `.tgz` files (no pack script runs, no tarballs in `docs/public/`, proxy middleware no longer excludes `.tgz`), these URLs will 404. Users clicking the Preview badge and copying the install command will get broken commands.
**Fix explanation:**
Added a `tarballsUrl` prop to `PreviewBadge` sourced from a new `TARBALLS_URL` environment variable. In `page.tsx`, the env var is read and passed to the component. In `preview-badge.tsx`, the tarball URLs are constructed using `tarballsUrl` when available, falling back to `deploymentUrl` for backwards compatibility.
The `TARBALLS_URL` environment variable needs to be configured in the Vercel docs project settings (pointing to the tarballs project's deployment URL). This follows the same pattern as `VERCEL_URL` — it's a hostname without protocol, and `https://` is prepended in the code.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: VaguelySerious <mittgfu@gmail.com>
- pack.ts now generates a public/index.html listing every published
package with copyable `pnpm i …` install commands, so the bare
deployment URL is itself a useful landing page when shared.
- Drop the OIDC trusted-sources bypass from the tarballs smoke and CI
workflow. The tarballs project must be publicly accessible (no
Deployment Protection) for `pnpm install` to fetch tarball URLs from
third-party projects, so the smoke now makes unauthenticated requests
and fails loudly on a login redirect.
- README documents the public-access requirement and the index page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
export function PreviewBadge({ deploymentUrl }: PreviewBadgeProps) {
const baseUrl = deploymentUrl.replace(/\/$/, '');
export function PreviewBadge({ deploymentUrl, tarballsUrl }: PreviewBadgeProps) {
const baseUrl = (tarballsUrl || deploymentUrl).replace(/\/$/, '');

@pranaygppranaygpMay 4, 2026

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.

honestly we don't need the tarballs link in docs preview-only page anymore for docs now. the tarballs project should just have an index web page that has this information and docs can be simplified

can do in follow up to unblock here

@github-actions

Copy link
Copy Markdown
Contributor

Backport to stable failed — unexpected error before the cherry-pick could be attempted. See workflow run.

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

Labels

backport-stableCherry-pick this PR to the stable branch when merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@VaguelySerious@pranaygp