Skip to content

fix(cloudflare, vercel-edge): Disable timer-based flush for serverless runtimes#20889

Open
sergical wants to merge 1 commit into
developfrom
feat/disable-flush-timer-serverless
Open

fix(cloudflare, vercel-edge): Disable timer-based flush for serverless runtimes#20889
sergical wants to merge 1 commit into
developfrom
feat/disable-flush-timer-serverless

Conversation

@sergical
Copy link
Copy Markdown
Member

Summary

  • Adds _flushInterval internal option to ClientOptions — controls the idle flush timer interval for logs/metrics weight-based flushing
  • When set to 0, skips setTimeout entirely; size-based flush (800KB) and explicit flush() still work
  • Sets _flushInterval: 0 in CloudflareClient and VercelEdgeClient

Context

The core client's setupWeightBasedFlushing schedules a setTimeout(fn, 5000) after each metric/log capture. In Cloudflare Workers built with @cloudflare/vite-plugin (native ESM + no_bundle: true), workerd rejects this timer as running outside request context — even though the code executes within a withSentry handler.

This does not affect Wrangler's single-bundle output. The difference is how workerd tracks request context across ESM module boundaries with no_bundle: true.

Zero performance impact for serverless — each request creates its own client, so the batching window never spans multiple requests. withSentryflushAndDispose already calls flush() at end of every request.

Fixes #20888
Reported stack trace: #20888 (comment)

Test plan

  • New test: _flushInterval: 0 prevents timer creation (no safeUnref call)
  • New test: _flushInterval: 0 still flushes via flush event
  • New test: _flushInterval: 0 still flushes on 800KB size threshold
  • All existing weight-based flushing tests pass (default behavior unchanged)
  • Build passes for @sentry/core, @sentry/cloudflare, @sentry/vercel-edge

🤖 Generated with Claude Code

…s runtimes

The weight-based flushing mechanism for logs and metrics schedules a
`setTimeout(fn, 5000)` after each capture. In Cloudflare Workers built
with `@cloudflare/vite-plugin` (native ESM + `no_bundle: true`), workerd
rejects this timer as running outside request context.

Add a `_flushInterval` internal option to `ClientOptions`. When set to 0,
the idle flush timer is skipped entirely. Size-based flushing (800KB) and
explicit `flush()` calls (via `withSentry` → `flushAndDispose`) still work.

Set `_flushInterval: 0` in `CloudflareClient` and `VercelEdgeClient`.

Fixes #20888

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sergical sergical requested a review from a team as a code owner May 14, 2026 18:26
@github-actions
Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 26.94 kB +0.07% +18 B 🔺
@sentry/browser - with treeshaking flags 25.37 kB +0.06% +13 B 🔺
@sentry/browser (incl. Tracing) 44.85 kB +0.04% +15 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 46.85 kB +0.04% +18 B 🔺
@sentry/browser (incl. Tracing, Profiling) 49.84 kB +0.03% +13 B 🔺
@sentry/browser (incl. Tracing, Replay) 84.46 kB +0.02% +13 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 73.93 kB +0.03% +15 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 89.16 kB +0.02% +13 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 101.81 kB +0.02% +12 B 🔺
@sentry/browser (incl. Feedback) 44.13 kB +0.05% +19 B 🔺
@sentry/browser (incl. sendFeedback) 31.75 kB +0.06% +17 B 🔺
@sentry/browser (incl. FeedbackAsync) 36.86 kB +0.06% +20 B 🔺
@sentry/browser (incl. Metrics) 28.03 kB +0.06% +15 B 🔺
@sentry/browser (incl. Logs) 28.17 kB +0.06% +16 B 🔺
@sentry/browser (incl. Metrics & Logs) 28.85 kB +0.05% +14 B 🔺
@sentry/react 28.69 kB +0.06% +15 B 🔺
@sentry/react (incl. Tracing) 47.12 kB +0.04% +17 B 🔺
@sentry/vue 31.86 kB +0.05% +13 B 🔺
@sentry/vue (incl. Tracing) 46.72 kB +0.03% +14 B 🔺
@sentry/svelte 26.96 kB +0.08% +19 B 🔺
CDN Bundle 29.33 kB +0.08% +21 B 🔺
CDN Bundle (incl. Tracing) 47.24 kB +0.04% +16 B 🔺
CDN Bundle (incl. Logs, Metrics) 30.7 kB +0.05% +15 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 48.38 kB +0.04% +18 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 70.06 kB +0.02% +10 B 🔺
CDN Bundle (incl. Tracing, Replay) 84.67 kB +0.03% +18 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 85.75 kB +0.04% +32 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 90.48 kB +0.02% +18 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 91.58 kB +0.03% +20 B 🔺
CDN Bundle - uncompressed 86.32 kB +0.06% +48 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 141.88 kB +0.04% +47 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 90.52 kB +0.06% +48 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 145.34 kB +0.04% +47 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 215.37 kB +0.03% +48 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 260.61 kB +0.02% +47 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 264.06 kB +0.02% +47 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 274.31 kB +0.02% +47 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 277.75 kB +0.02% +47 B 🔺
@sentry/nextjs (client) 49.62 kB +0.03% +13 B 🔺
@sentry/sveltekit (client) 45.33 kB +0.04% +15 B 🔺
@sentry/node-core 61.98 kB +0.03% +14 B 🔺
@sentry/node 166.94 kB +0.02% +19 B 🔺
@sentry/node - without tracing 74.39 kB +0.03% +15 B 🔺
@sentry/aws-serverless 109.19 kB +0.02% +14 B 🔺
@sentry/cloudflare (withSentry) - minified 170.96 kB +0.05% +74 B 🔺
@sentry/cloudflare (withSentry) 431.26 kB +0.04% +157 B 🔺

View base workflow run

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sentry.metrics.* triggers setTimeout outside request context in Cloudflare Workers

1 participant