[world-vercel] Send remoteRefBehavior=lazy on v4 metadata-only event listings#2415
[world-vercel] Send remoteRefBehavior=lazy on v4 metadata-only event listings#2415VaguelySerious wants to merge 1 commit into
Conversation
getWorkflowRunEvents applied resolveData only client-side: it always downloaded the resolved payload bytes for every event, then discarded them when resolveData was 'none'. The v4 list endpoints accept remoteRefBehavior (resolve|lazy, default resolve), so map resolveData 'none' → lazy and send it on the runId and correlationId list queries — the backend then emits empty-body frames and skips the per-event blob read. Safe against a backend that predates the flag: it ignores the param and streams full bodies, and buildEventFromV4 still strips them for resolveData 'none', so this is a pure bandwidth optimization either way. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 3d5ed93 The changes in this PR will be included in the next version bump. This PR includes changesets to release 17 packages
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 |
🧪 E2E Test Results✅ All tests passed Summary
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
✅ 📋 Other
|
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 25 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 50 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.all with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro Promise.race with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 10 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 25 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 50 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 10 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 25 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 50 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) stream pipeline with 5 transform steps (1MB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express 10 parallel streams (1MB each)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro fan-out fan-in 10 streams (1MB each)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
|
What
getWorkflowRunEventsappliedresolveDataonly client-side: on the v4 wire it always downloaded the resolved payload bytes for every event (step inputs/outputs, run input/output, hook payloads, errors), then discarded them inbuildEventFromV4whenresolveDatawas'none'. Pure wasted bandwidth for metadata-only consumers — and v4 has no per-event/refspath to opt out of.The v4 list endpoints already accept
remoteRefBehavior(resolve|lazy, defaultresolve). This mapsresolveData: 'none'→remoteRefBehavior: 'lazy'and sends it on both the runId and correlationId list queries, so the backend emits empty-body frames and skips the per-event blob read entirely.resolveData: 'all'sendsresolve(the default), unchanged.This is the SDK half of the metadata-only-listing optimization; it pairs with the backend change that honors
remoteRefBehavior=lazyon the v4 list/stream.Why it's safe
remoteRefBehaviorparam — the same one v2/v3 use, whichresolveDatahas always mapped to.buildEventFromV4still strips them forresolveData: 'none'. So correctness holds regardless of backend version — it's purely a bandwidth optimization that kicks in once the backend supports it.Test plan
getWorkflowRunEvents({ resolveData: 'none' })sends?remoteRefBehavior=lazyand strips any body the backend still returns (events.test.ts)resolveData: 'all') sends?remoteRefBehavior=resolveand splices the body bytes intoeventDataappendListParams)