') + ')', '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('^' + ".*" + ', '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" + ', '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('^' + ".*" + ', '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); } })(); })(); Retry transient connection timeouts by NathanColosimo · Pull Request #3013 · vercel/workflow · GitHub
Skip to content

Retry transient connection timeouts - #3013

Merged
NathanColosimo merged 5 commits into
mainfrom
codex/retry-connect-timeouts
Jul 20, 2026
Merged

Retry transient connection timeouts#3013
NathanColosimo merged 5 commits into
mainfrom
codex/retry-connect-timeouts

Conversation

@NathanColosimo

@NathanColosimoNathanColosimo commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Retries a connection timeout once while reading an existing Workflow run.

Eve resumes active sessions by reading their Workflow runs. A brief pre-connection failure can fail delivery even though the session remains active. Retrying only this safe run read allows Eve to continue using the existing run without changing the global retry policy.

Validated with the world-vercel build, test suite, and typecheck.

@vercel

vercelBot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

@changeset-bot

changeset-botBot commented Jul 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f442621

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

@github-actions

github-actionsBot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

📊 Workflow Benchmarks

commit f442621 · Mon, 20 Jul 2026 23:26:04 GMT · run logs

Backend: vercel · app: nextjs-turbopack

MetricScenarioBest (ms)P75 (ms)P90 (ms)P99 (ms)Samples
TTFSstep1260 (+24%) 🔻1356 🔴 (+16%) 🔻1380 🔴 (+16%) 🔻1424 🔴 (-20%) 💚30
TTFSstream313 (-69%) 💚1371 🔴 (+22%) 🔻1405 🔴 (+21%) 🔻1423 🔴 (+16%) 🔻30
TTFShook + stream1467 (+20%) 🔻1606 🔴 (+13%)1622 🔴 (+13%)1808 🔴 (+17%) 🔻30
STSO1020 steps (1-20)145 (-29%) 💚312 🔴 (+2.0%)356 🔴 (-18%) 💚483 🔴 (-8.3%)19
STSO1020 steps (101-120)195 (-7.1%)277 🔴 (-7.0%)290 🔴 (-8.5%)600 🔴 (+74%) 🔻19
STSO1020 steps (1001-1020)476 (-16%) 💚551 🔴 (-18%) 💚712 🔴 (-5.1%)1054 🔴 (+34%) 🔻19
WO1020 steps400968 (-13%)400968 (-13%)400968 (-13%)400968 (-13%)1
SLstream latency98 (-3.9%)178 🔴 (+16%) 🔻219 🔴 (+30%) 🔻441 🔴 (+55%) 🔻30
📜 Previous results (3)

2497f75

Mon, 20 Jul 2026 22:42:01 GMT · run logs

vercel / nextjs-turbopack

MetricScenarioBest (ms)P75 (ms)P90 (ms)P99 (ms)Samples
TTFSstep256 (-75%) 💚1286 🔴 (+10%)1326 🔴 (+12%)1340 🔴 (-24%) 💚30
TTFSstream248 (-75%) 💚1297 🔴 (+15%) 🔻1326 🔴 (+14%)1601 🔴 (+30%) 🔻30
TTFShook + stream525 (-57%) 💚1548 🔴 (+8.8%)1584 🔴 (+11%)1707 🔴 (+11%)30
STSO1020 steps (1-20)191 (-6.8%)295 🔴 (-3.6%)385 🔴 (-11%)467 🔴 (-11%)19
STSO1020 steps (101-120)216 (+2.9%)333 🔴 (+12%)396 🔴 (+25%) 🔻1972 🔴 (+472%) 🔻19
STSO1020 steps (1001-1020)468 (-17%) 💚533 🔴 (-20%) 💚614 🔴 (-18%) 💚971 🔴 (+23%) 🔻19
WO1020 steps420258 (-9.3%)420258 (-9.3%)420258 (-9.3%)420258 (-9.3%)1
SLstream latency104 (+2.0%)193 🔴 (+25%) 🔻249 🔴 (+48%) 🔻471 🔴 (+66%) 🔻30

26dac3b

Mon, 20 Jul 2026 21:40:07 GMT · run logs

vercel / nextjs-turbopack

MetricScenarioBest (ms)P75 (ms)P90 (ms)P99 (ms)Samples
TTFSstep180 (-82%) 💚1262 🔴 (+8.2%)1292 🔴 (+8.8%)1343 🔴 (-24%) 💚30
TTFSstream200 (-80%) 💚1256 🔴 (+11%)1284 🔴 (+10%)1452 🔴 (+18%) 🔻30
TTFShook + stream516 (-58%) 💚1514 🔴 (+6.4%)1541 🔴 (+7.7%)1624 🔴 (+5.2%)30
STSO1020 steps (1-20)180 (-12%)281 🔴 (-8.2%)358 🔴 (-18%) 💚497 🔴 (-5.7%)19
STSO1020 steps (101-120)203 (-3.3%)280 🔴 (-6.0%)359 🔴 (+13%)415 🔴 (+20%) 🔻19
STSO1020 steps (1001-1020)488 (-14%)619 🔴 (-7.5%)709 🔴 (-5.5%)747 🔴 (-5.2%)19
WO1020 steps414967 (-10%)414967 (-10%)414967 (-10%)414967 (-10%)1
SLstream latency98 (-3.9%)200 🔴 (+30%) 🔻250 🔴 (+49%) 🔻398 🔴 (+40%) 🔻30

55d7f09

Mon, 20 Jul 2026 21:24:00 GMT · run logs

vercel / nextjs-turbopack

MetricScenarioBest (ms)P75 (ms)P90 (ms)P99 (ms)Samples
TTFSstep1283 (+82%) 🔻1396 🔴 (+28%) 🔻1430 🔴 (+23%) 🔻1639 🔴 (-3.0%)30
TTFSstream1287 (+31%) 🔻1423 🔴 (+32%) 🔻1446 🔴 (+31%) 🔻1501 🔴 (+29%) 🔻30
TTFShook + stream564 (-55%) 💚1657 🔴 (+22%) 🔻1718 🔴 (+20%) 🔻5862 🔴 (+286%) 🔻30
STSO1020 steps (1-20)199 (+8.7%)319 🔴 (+26%) 🔻341 🔴 (+16%) 🔻404 🔴 (+32%) 🔻19
STSO1020 steps (101-120)212 (+5.5%)326 🔴 (-21%) 💚380 🔴 (-18%) 💚2385 🔴 (+341%) 🔻19
STSO1020 steps (1001-1020)479 (+1.5%)553 🔴 (+4.1%)567 🔴 (+1.6%)602 🔴 (+2.4%)19
WO1020 steps416967 (+4.6%)416967 (+4.6%)416967 (+4.6%)416967 (+4.6%)1
SLstream latency94 (+19%) 🔻169 🔴 (+31%) 🔻357 🔴 (+148%) 🔻601 🔴 (+285%) 🔻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 20, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

PassedFailedSkippedTotal
✅ ▲ Vercel Production145302301683
✅ 💻 Local Development161702191836
✅ 📦 Local Production161702191836
✅ 🐘 Local Postgres161702191836
✅ 🪟 Windows15300153
✅ 📋 Other102002041224
✅ vercel-multi-region270027
Total7504010918595

Details by Category

✅ ▲ Vercel Production
AppPassedFailedSkipped
✅ astro126027
✅ example126027
✅ express126027
✅ fastify126027
✅ hono126027
✅ nextjs-turbopack15003
✅ nextjs-webpack15003
✅ nitro126027
✅ nuxt126027
✅ sveltekit14508
✅ vite126027
✅ 💻 Local Development
AppPassedFailedSkipped
✅ astro-stable128025
✅ express-stable128025
✅ fastify-stable128025
✅ hono-stable128025
✅ nextjs-turbopack-canary134019
✅ nextjs-turbopack-stable15300
✅ nextjs-webpack-canary134019
✅ nextjs-webpack-stable15300
✅ nitro-stable128025
✅ nuxt-stable128025
✅ sveltekit-stable14706
✅ vite-stable128025
✅ 📦 Local Production
AppPassedFailedSkipped
✅ astro-stable128025
✅ express-stable128025
✅ fastify-stable128025
✅ hono-stable128025
✅ nextjs-turbopack-canary134019
✅ nextjs-turbopack-stable15300
✅ nextjs-webpack-canary134019
✅ nextjs-webpack-stable15300
✅ nitro-stable128025
✅ nuxt-stable128025
✅ sveltekit-stable14706
✅ vite-stable128025
✅ 🐘 Local Postgres
AppPassedFailedSkipped
✅ astro-stable128025
✅ express-stable128025
✅ fastify-stable128025
✅ hono-stable128025
✅ nextjs-turbopack-canary134019
✅ nextjs-turbopack-stable15300
✅ nextjs-webpack-canary134019
✅ nextjs-webpack-stable15300
✅ nitro-stable128025
✅ nuxt-stable128025
✅ sveltekit-stable14706
✅ vite-stable128025
✅ 🪟 Windows
AppPassedFailedSkipped
✅ nextjs-turbopack15300
✅ 📋 Other
AppPassedFailedSkipped
✅ e2e-local-dev-nest-stable128025
✅ e2e-local-dev-tanstack-start-128025
✅ e2e-local-postgres-nest-stable128025
✅ e2e-local-postgres-tanstack-start-128025
✅ e2e-local-prod-nest-stable128025
✅ e2e-local-prod-tanstack-start-128025
✅ e2e-vercel-prod-nest126027
✅ e2e-vercel-prod-tanstack-start126027
✅ vercel-multi-region
AppPassedFailedSkipped
✅ nextjs-turbopack2700

📋 View full workflow run

Signed-off-by: Nathan Colosimo <110621881+NathanColosimo@users.noreply.github.com>
…imeouts
Signed-off-by: Nathan Colosimo <110621881+NathanColosimo@users.noreply.github.com>
@github-actionsgithub-actionsBot mentioned this pull request Jul 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Backport PR opened against stable: #3019. Merge conflicts were resolved by AI — please review carefully. (backport job run)

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

@NathanColosimo@VaguelySerious