Skip to content

test(e2e): force storage-backed inspect listings (read-your-writes) via WORKFLOW_DISABLE_ANALYTICS_READS - #3062

Merged
karthikscale3 merged 2 commits into
mainfrom
kk/e2e-events-readback-poll
Jul 23, 2026
Merged

test(e2e): force storage-backed inspect listings (read-your-writes) via WORKFLOW_DISABLE_ANALYTICS_READS#3062
karthikscale3 merged 2 commits into
mainfrom
kk/e2e-events-readback-poll

Conversation

@karthikscale3

@karthikscale3karthikscale3 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Problem

The e2e suites assert on workflow inspect listings (events, steps) immediately after run completion. Those listings prefer the world's analytics read namespace, which is served from an eventually-ingested store — a read racing ingestion can return a page that includes the run's earlier rows but not the freshest ones, so the CLI's empty-page storage fallback doesn't trigger and the assertion fails.

Observed fingerprints (all with the run demonstrably completed with correct status/output):

  • stepFunctionPassingWorkflow: expected [] to have a length of 1 on the step_completed events readback (two CI occurrences on different lanes).
  • instanceMethodStepWorkflow: counterSteps.every(status === 'completed') false on the steps listing — same race, different resource (two occurrences on different lanes/days).

Fix

Deterministic rather than bounded-wait (supersedes the earlier poll commit):

  1. @workflow/world-vercel: WORKFLOW_DISABLE_ANALYTICS_READS=1 opts the world's analytics namespace off, so every inspect list path falls back to strongly consistent primary storage.
  2. e2e cliInspectJson sets that env for its spawned CLI invocations — every entity readback in the suites becomes read-your-writes, covering both observed variants and any future listing assertions, with no per-test changes.

Production behavior is unchanged (the env is opt-in); the analytics-backed listings remain the CLI default everywhere else.

🤖 Generated with Claude Code

@karthikscale3
karthikscale3 requested review from a team and ijjk as code ownersJuly 23, 2026 05:20
@changeset-bot

changeset-botBot commented Jul 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 49fe560

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

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

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 Jul 23, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actionsBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

📊 Workflow Benchmarks

commit 49fe560 · Thu, 23 Jul 2026 21:31:22 GMT · run logs

Backend: vercel · app: nextjs-turbopack

MetricScenarioBest (ms)P75 (ms)P90 (ms)P99 (ms)Samples
TTFSstep1299 (+27%) 🔻1370 🔴 (+11%)1412 🔴 (+12%)1675 🔴 (+25%) 🔻30
TTFSstream1218 (+209%) 🔻1364 🔴 (+20%) 🔻1401 🔴 (+15%) 🔻3380 🔴 (-2.6%)30
TTFShook + stream486 (-19%) 💚1556 🔴 (+6.3%)1662 🔴 (+9.4%)1987 🔴 (+21%) 🔻30
STSO1020 steps (1-20)145 (-29%) 💚291 🔴 (-8.8%)359 🔴 (+5.3%)434 🔴 (+16%) 🔻19
STSO1020 steps (101-120)189 (-13%)247 🔴 (-17%) 💚261 🔴 (-35%) 💚264 🔴 (-49%) 💚19
STSO1020 steps (1001-1020)455 (-13%)568 🔴 (-8.2%)610 🔴 (-17%) 💚752 🔴 (±0%)19
WO1020 steps382412 (-19%) 💚382412 (-19%) 💚382412 (-19%) 💚382412 (-19%) 💚1
SLstream latency83 (-15%) 💚147 🔴 (-32%) 💚152 🔴 (-41%) 💚576 🔴 (+93%) 🔻30
📜 Previous results (2)

d1a0ee2

Thu, 23 Jul 2026 19:00:00 GMT · run logs

vercel / nextjs-turbopack

MetricScenarioBest (ms)P75 (ms)P90 (ms)P99 (ms)Samples
TTFSstep236 (-3.7%)1332 🔴 (+19%) 🔻1344 🔴 (+17%) 🔻1550 🔴 (+1.3%)30
TTFSstream207 (+6.7%)1312 🔴 (+21%) 🔻1343 🔴 (+20%) 🔻1366 🔴 (+6.9%)30
TTFShook + stream544 (+51%) 🔻1566 🔴 (+19%) 🔻1612 🔴 (+10%)1818 🔴 (±0%)30
STSO1020 steps (1-20)179 (-0.6%)294 🔴 (-27%) 💚359 🔴 (-27%) 💚443 🔴 (-22%) 💚19
STSO1020 steps (101-120)198 (-1.0%)277 🔴 (+4.9%)315 🔴 (-20%) 💚316 🔴 (-51%) 💚19
STSO1020 steps (1001-1020)495 (-1.4%)595 🔴 (+2.2%)644 🔴 (+2.2%)690 🔴 (+7.0%)19
WO1020 steps410608 (-3.7%)410608 (-3.7%)410608 (-3.7%)410608 (-3.7%)1
SLstream latency101 (+15%)149 🔴 (+3.5%)165 🔴 (-6.3%)239 🔴 (+1.7%)30

b9f18ec

Thu, 23 Jul 2026 05:36:51 GMT · run logs

vercel / nextjs-turbopack

MetricScenarioBest (ms)P75 (ms)P90 (ms)P99 (ms)Samples
TTFSstep305 (+91%) 🔻1344 🔴 (+232%) 🔻1356 🔴 (+192%) 🔻1634 🔴 (+212%) 🔻30
TTFSstream247 (+49%) 🔻1293 🔴 (+392%) 🔻1314 🔴 (+339%) 🔻1443 🔴 (+186%) 🔻30
TTFShook + stream1446 (+333%) 🔻1576 🔴 (+186%) 🔻1585 🔴 (+153%) 🔻1670 🔴 (+104%) 🔻30
STSO1020 steps (1-20)173 (-9.9%)291 🔴 (-3.6%)347 🔴 (-0.9%)551 🔴 (-20%) 💚19
STSO1020 steps (101-120)184 (-25%) 💚268 🔴 (-29%) 💚300 🔴 (-40%) 💚333 🔴 (-47%) 💚19
STSO1020 steps (1001-1020)465 (-32%) 💚534 🔴 (-39%) 💚744 🔴 (-27%) 💚831 🔴 (-19%) 💚19
WO1020 steps395703 (-41%) 💚395703 (-41%) 💚395703 (-41%) 💚395703 (-41%) 💚1
SLstream latency93 (+12%)162 🔴 (+35%) 🔻247 🔴 (+36%) 🔻380 🔴 (+11%)30

Best/P75/P90/P99 deltas compare against the most recent benchmark run on main at the time of this run. 🔻 flags a delta worse than +15%, 💚 one better than −15%.

Metrics — TTFS: time to first step body (in-deployment start() → first step body, deployment clocks) · STSO: step-to-step overhead (gap between consecutive step bodies) · WO: workflow overhead (whole-run time outside step bodies, in-deployment anchored) · SL: stream latency (in-deployment write → read propagation, readAt - writtenAt)

Scenarios — step: one trivial no-op step, no stream; no hooks, so the run stays in turbo mode (in-process fast path) · stream: one streaming step; no hooks, so the run stays in turbo mode (in-process fast path) · hook + stream: registers a hook before one step, which exits turbo mode (dispatch path) · 1020 steps: 1020 trivial sequential steps; STSO is measured between consecutive steps in the given step ranges, and WO is the whole-run overhead outside step bodies · stream latency: parallel reader/writer steps on a dedicated stream; SL is the in-deployment write->read propagation (readAt - writtenAt)

🔴 marks a percentile over its target (within target is left unmarked). Targets (p75/p90/p99, ms) — TTFS 200/300/600 · SL 50/60/125 · STSO (1-20) 20/30/60 · STSO (101-120) 30/45/90 · STSO (1001-1020) 40/60/120

All metrics are measured from deployment-side timestamps only. Runs are triggered by an in-deployment route that stamps the anchor (clientStart) right before start(), so the CI runner’s request and its path through api.vercel.com sit outside every measured window. TTFS = in-deployment start() → first step body (turbo uses the in-process fast path, non-turbo the dispatch path), and includes the VQS dispatch hop plus any /flow cold start. STSO/WO are measured between step bodies on the deployment. SL is measured inside the workflow (parallel reader/writer steps), so it no longer includes the api.vercel.com read path.

Cold starts are kept in the numbers on purpose — they are part of real bursty-workload latency. The workbench deployment cold-starts the /flow invocation for a large fraction of runs, inflating P75+; the Best column shows the fastest (warm-start) sample for comparison.

@github-actions

github-actionsBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production145502391694
✅ 💻 Local Development162102271848
✅ 📦 Local Production162102271848
✅ 🐘 Local Postgres162102271848
✅ 📋 Other102002121232
✅ vercel-multi-region270027
Total7365011328497

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro126028
✅ example126028
✅ express126028
✅ fastify126028
✅ hono126028
✅ nextjs-turbopack15103
✅ nextjs-webpack15103
✅ nitro126028
✅ nuxt126028
✅ sveltekit14509
✅ vite126028
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable128026
✅ express-stable128026
✅ fastify-stable128026
✅ hono-stable128026
✅ nextjs-turbopack-canary135019
✅ nextjs-turbopack-stable15400
✅ nextjs-webpack-canary135019
✅ nextjs-webpack-stable15400
✅ nitro-stable128026
✅ nuxt-stable128026
✅ sveltekit-stable14707
✅ vite-stable128026
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable128026
✅ express-stable128026
✅ fastify-stable128026
✅ hono-stable128026
✅ nextjs-turbopack-canary135019
✅ nextjs-turbopack-stable15400
✅ nextjs-webpack-canary135019
✅ nextjs-webpack-stable15400
✅ nitro-stable128026
✅ nuxt-stable128026
✅ sveltekit-stable14707
✅ vite-stable128026
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable128026
✅ express-stable128026
✅ fastify-stable128026
✅ hono-stable128026
✅ nextjs-turbopack-canary135019
✅ nextjs-turbopack-stable15400
✅ nextjs-webpack-canary135019
✅ nextjs-webpack-stable15400
✅ nitro-stable128026
✅ nuxt-stable128026
✅ sveltekit-stable14707
✅ vite-stable128026
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable128026
✅ e2e-local-dev-tanstack-start-128026
✅ e2e-local-postgres-nest-stable128026
✅ e2e-local-postgres-tanstack-start-128026
✅ e2e-local-prod-nest-stable128026
✅ e2e-local-prod-tanstack-start-128026
✅ e2e-vercel-prod-nest126028
✅ e2e-vercel-prod-tanstack-start126028
✅ vercel-multi-region
AppPassedFailedSkipped
✅ nextjs-turbopack2700

📋 View full workflow run


Some E2E test jobs failed:

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

Check the workflow run for details.

…_ANALYTICS_READS
The analytics store ingests asynchronously; e2e assertions read events
and steps immediately after run completion and can catch a page missing
the freshest rows (observed as stepFunctionPassingWorkflow's
step_completed readback returning empty, and the same race on steps
listings in other suites). Instead of polling each readback, disable
the analytics namespace for the e2e's CLI invocations so every inspect
listing is served read-your-writes from primary storage. Replaces the
earlier bounded poll with the deterministic mechanism.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@karthikscale3
karthikscale3force-pushed the kk/e2e-events-readback-poll branch from d1a0ee2 to 49fe560CompareJuly 23, 2026 21:15
@karthikscale3karthikscale3 changed the title test(e2e): make the events readback robust to analytics ingestion lagtest(e2e): force storage-backed inspect listings (read-your-writes) via WORKFLOW_DISABLE_ANALYTICS_READSJul 23, 2026
@karthikscale3
karthikscale3 merged commit 313a074 into mainJul 23, 2026
104 of 106 checks passed
@karthikscale3
karthikscale3 deleted the kk/e2e-events-readback-poll branch July 23, 2026 21:43
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for 313a074 (AI decision).

This change builds entirely on the analytics read namespace (createAnalytics) in @workflow/world-vercel, which exists only on main — verified via git grep analytics origin/stable -- packages/world-vercel/src/ (no matches) and origin/stable:packages/world-vercel/src/index.ts (no analytics wiring). On stable, inspect listings are already served from primary storage, so the eventual-consistency race this fixes cannot occur and the new WORKFLOW_DISABLE_ANALYTICS_READS env var would be a no-op.

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

313a074ad17f8acbc82e04e6eea77c63439a1df8

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@karthikscale3@VaguelySerious