Skip to content

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

Merged
JPeer264 merged 1 commit into
developfrom
feat/disable-flush-timer-serverless
May 20, 2026
Merged

fix(cloudflare, vercel-edge): Disable timer-based flush for serverless runtimes#20889
JPeer264 merged 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

@sergical sergical requested a review from a team as a code owner May 14, 2026 18:26
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 26.94 kB +0.08% +19 B 🔺
@sentry/browser - with treeshaking flags 25.36 kB +0.05% +12 B 🔺
@sentry/browser (incl. Tracing) 44.93 kB +0.04% +15 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 47.17 kB +0.03% +14 B 🔺
@sentry/browser (incl. Tracing, Profiling) 49.92 kB +0.03% +14 B 🔺
@sentry/browser (incl. Tracing, Replay) 84.56 kB +0.02% +13 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 74.06 kB +0.02% +13 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 89.26 kB +0.02% +12 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 101.89 kB +0.02% +15 B 🔺
@sentry/browser (incl. Feedback) 44.12 kB +0.05% +20 B 🔺
@sentry/browser (incl. sendFeedback) 31.75 kB +0.06% +17 B 🔺
@sentry/browser (incl. FeedbackAsync) 36.86 kB +0.06% +19 B 🔺
@sentry/browser (incl. Metrics) 28.02 kB +0.06% +15 B 🔺
@sentry/browser (incl. Logs) 28.17 kB +0.06% +15 B 🔺
@sentry/browser (incl. Metrics & Logs) 28.85 kB +0.05% +14 B 🔺
@sentry/react 28.68 kB +0.06% +16 B 🔺
@sentry/react (incl. Tracing) 47.18 kB +0.04% +16 B 🔺
@sentry/vue 31.86 kB +0.05% +14 B 🔺
@sentry/vue (incl. Tracing) 46.79 kB +0.03% +14 B 🔺
@sentry/svelte 26.96 kB +0.07% +17 B 🔺
CDN Bundle 29.35 kB +0.05% +14 B 🔺
CDN Bundle (incl. Tracing) 47.49 kB +0.04% +18 B 🔺
CDN Bundle (incl. Logs, Metrics) 30.72 kB +0.05% +14 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 48.61 kB +0.05% +20 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 70.04 kB +0.02% +12 B 🔺
CDN Bundle (incl. Tracing, Replay) 84.96 kB +0.03% +22 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.01 kB +0.03% +19 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 90.82 kB +0.03% +21 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 91.89 kB +0.02% +16 B 🔺
CDN Bundle - uncompressed 86.51 kB +0.06% +48 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 142.98 kB +0.04% +47 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 90.7 kB +0.06% +48 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 146.44 kB +0.04% +47 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 215.43 kB +0.03% +48 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 261.76 kB +0.02% +47 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 265.2 kB +0.02% +47 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 275.46 kB +0.02% +47 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 278.89 kB +0.02% +47 B 🔺
@sentry/nextjs (client) 49.68 kB +0.04% +16 B 🔺
@sentry/sveltekit (client) 45.42 kB +0.04% +14 B 🔺
@sentry/core/server 75.77 kB +0.03% +22 B 🔺
@sentry/core/browser 62.55 kB +0.05% +27 B 🔺
@sentry/node-core 62.23 kB +0.03% +13 B 🔺
@sentry/node 164.39 kB +0.02% +19 B 🔺
@sentry/node - without tracing 74.67 kB +0.03% +16 B 🔺
@sentry/aws-serverless 86.88 kB +0.03% +19 B 🔺
@sentry/cloudflare (withSentry) - minified 171.6 kB +0.05% +74 B 🔺
@sentry/cloudflare (withSentry) 429.78 kB +0.04% +157 B 🔺

View base workflow run

Copy link
Copy Markdown
Member

@JPeer264 JPeer264 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds reasonable tbh. I think we also have to think about adding E2E tests that are using the vite plugin. I think we don't have that at the moment, but I can take care of it if you want.

Is there somewhere a repro online which can be used for a minimal E2E test?

…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>
@JPeer264 JPeer264 force-pushed the feat/disable-flush-timer-serverless branch from 20b4b26 to 68155d7 Compare May 20, 2026 12:31
@JPeer264 JPeer264 enabled auto-merge (squash) May 20, 2026 12:32
@JPeer264 JPeer264 merged commit 95b909e into develop May 20, 2026
263 of 264 checks passed
@JPeer264 JPeer264 deleted the feat/disable-flush-timer-serverless branch May 20, 2026 12:49
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

2 participants