From fac1de3edf1b22fdcac666af83233a5b1424b349 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Tue, 5 May 2026 16:20:02 +0200 Subject: [PATCH 01/12] docs(js): add Node stream spans guide --- .../node/tracing/stream-spans/index.mdx | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx diff --git a/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx b/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx new file mode 100644 index 0000000000000..3e4c257ef8cf5 --- /dev/null +++ b/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx @@ -0,0 +1,174 @@ +--- +title: Stream Spans +description: "Learn how to use streamed spans to remove the 1000 span limit, reduce memory usage, and get faster visibility into your traces." +sidebar_order: 50 +new: true +--- + +By default, the Sentry Node.js SDK collects all spans in memory and sends them as a single transaction once the root span ends. Streamed spans change this model: spans are sent incrementally in batches as they finish, rather than waiting for the entire transaction to complete. + +## Why Use Streamed Spans + +- **No 1000 span limit.** Transactions are capped at 1000 spans. With streamed spans, there is no upper limit since spans are sent in batches. +- **Lower memory usage.** Spans are flushed periodically and don't need to be held in memory until the root span ends. This is especially useful for long-running processes like queue consumers or cron jobs. +- **Faster visibility.** Span data arrives in Sentry as your application runs, instead of only after the entire operation completes. +- **No data loss from crashes.** If your process terminates unexpectedly, spans that were already flushed are preserved. With transactions, a crash before the root span ends means all span data is lost. + +## Enable Streamed Spans + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + +```javascript {filename:instrument.js} +const Sentry = require("@sentry/node"); + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + +When `traceLifecycle` is set to `'static'` (the default), traces are sent as transactions. Setting it to `'stream'` enables span streaming. + +## Start a Span + +Starting spans works the same way as with transactions. Use `Sentry.startSpan()` to create a span that is automatically ended when the callback completes: + +```javascript +const result = await Sentry.startSpan( + { name: "my-operation", attributes: { "my.attribute": "value" } }, + async () => { + // Your code here + return await doWork(); + } +); +``` + +Child spans created inside the callback are automatically associated with the parent: + +```javascript +await Sentry.startSpan({ name: "parent-operation" }, async () => { + await Sentry.startSpan({ name: "child-step-1" }, async () => { + await stepOne(); + }); + + await Sentry.startSpan({ name: "child-step-2" }, async () => { + await stepTwo(); + }); +}); +``` + +With streaming enabled, each span is flushed to Sentry shortly after it ends instead of being held until the parent completes. + +For more details on span creation APIs (`startSpan`, `startSpanManual`, `startInactiveSpan`), see Instrumentation. + +## Attach Attributes + +Attributes let you attach structured metadata to spans. You can set them when starting a span: + +```javascript +Sentry.startSpan( + { + name: "process-order", + op: "queue.process", + attributes: { + "order.id": "abc-123", + "order.item_count": 5, + "order.priority": true, + }, + }, + () => { + // Process the order + } +); +``` + +Or add them to an already running span: + +```javascript +Sentry.startSpan({ name: "handle-request" }, (span) => { + // Set a single attribute + span.setAttribute("http.response.status_code", 200); + + // Set multiple attributes at once + span.setAttributes({ + "http.route": "/api/users", + "user.id": "user-42", + }); +}); +``` + +Attribute values can be `string`, `number`, or `boolean`, as well as arrays of these types. + +## Continue a Trace + +When you receive a request from an upstream service that includes Sentry trace headers, use `Sentry.continueTrace()` to connect your spans to the existing distributed trace: + +```javascript {filename:server.js} +const http = require("http"); +const Sentry = require("@sentry/node"); + +http.createServer((req, res) => { + Sentry.continueTrace( + { + sentryTrace: req.headers["sentry-trace"], + baggage: req.headers["baggage"], + }, + () => { + Sentry.startSpan({ name: `${req.method} ${req.url}` }, () => { + // Handle the request + res.end("OK"); + }); + } + ); +}); +``` + +To propagate the trace to downstream services, inject the trace headers into your outgoing requests: + +```javascript +await Sentry.startSpan({ name: "call-downstream" }, async () => { + const traceData = Sentry.getTraceData(); + + await fetch("https://downstream.example.com/api", { + headers: { + "sentry-trace": traceData["sentry-trace"], + baggage: traceData["baggage"], + }, + }); +}); +``` + +## Start a New Trace + +If you need to start a completely new trace that is not connected to the current one, use `Sentry.startNewTrace()`. This is useful for background jobs or scheduled tasks where you want a clean trace boundary: + +```javascript {filename:worker.js} +const Sentry = require("@sentry/node"); + +function processJob(job) { + Sentry.startNewTrace(() => { + Sentry.startSpan( + { + name: "process-job", + attributes: { "job.id": job.id, "job.type": job.type }, + }, + async () => { + await job.execute(); + } + ); + }); +} +``` + +Any spans created inside the `startNewTrace` callback belong to a fresh trace with a new trace ID. Once the callback ends, the SDK continues the previous trace (if one was active). + +## How Span Flushing Works + +When span streaming is enabled, the SDK maintains an internal buffer that groups spans by trace ID. Spans are flushed: + +- On a regular interval (every 5 seconds by default). +- When a trace's buffer reaches 1000 spans. +- When you call `Sentry.flush()` or `Sentry.close()`. + +Each flush sends only the spans that have accumulated since the last flush, grouped into envelopes by trace ID. From 4461c9cbafbbdec48dbbe965fa204dd49a04f794 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Mon, 11 May 2026 16:03:26 +0200 Subject: [PATCH 02/12] Add srubbing and filtering --- .../node/tracing/stream-spans/index.mdx | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx b/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx index 3e4c257ef8cf5..6f0c35973ca37 100644 --- a/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx +++ b/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx @@ -163,6 +163,64 @@ function processJob(job) { Any spans created inside the `startNewTrace` callback belong to a fresh trace with a new trace ID. Once the callback ends, the SDK continues the previous trace (if one was active). +## Scrub Span Data + +To modify or redact data on spans before they are sent, use `beforeSendSpan`. When using streamed spans, the hook must be wrapped with `Sentry.withStreamedSpan()` so the SDK applies it to spans as they are flushed rather than only at transaction time. + +If you don't have a `beforeSendSpan` hook, no extra setup is needed. + +```javascript {filename:instrument.js} +const Sentry = require("@sentry/node"); + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", + beforeSendSpan: Sentry.withStreamedSpan((span) => { + if (span.op === "db.query") { + span.description = "[filtered]"; + } + return span; + }), +}); +``` + +Without the wrapper, `beforeSendSpan` is silently skipped for streamed spans. + +`beforeSendSpan` can only modify span data — you cannot use it to drop spans. To prevent spans from being created entirely, use [`ignoreSpans`](#drop-spans-with-ignorespans) instead. + +### Drop Spans With `ignoreSpans` + +To prevent specific spans from being created, use the `ignoreSpans` option. Unlike `beforeSendSpan` (which can only modify spans), `ignoreSpans` drops matching spans before they start. You can match by span name using strings or regular expressions, or use an object to also match on span attributes: + +```javascript {filename:instrument.js} +const Sentry = require("@sentry/node"); + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", + ignoreSpans: [ + // Drop spans whose name contains "healthcheck" + "healthcheck", + // Drop spans whose name matches a pattern + /^GET \/api\/v1\/internal/, + // Drop spans matching name and attribute conditions + { + name: /^GET \//, + attributes: { + "http.response.status_code": 200, + "http.route": "/api/status", + }, + }, + ], +}); +``` + +If a matching span is a root span, all of its child spans are dropped as well. If a child span matches, only that span is dropped and its children are reparented to the next ancestor. + +If you need to redact or modify data on spans that aren't dropped, use [`beforeSendSpan`](#scrub-span-data) instead. + ## How Span Flushing Works When span streaming is enabled, the SDK maintains an internal buffer that groups spans by trace ID. Spans are flushed: From 29765bbd63a8657e122cd68c658332d5f19e97a3 Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Tue, 12 May 2026 08:43:26 +0200 Subject: [PATCH 03/12] clean up platform include files created for split layout update --- .../javascript/guides/angular/index.mdx | 2 +- .../guides/angular/manual-setup.mdx | 4 ++-- .../guides/azure-functions/index.mdx | 2 +- .../platforms/javascript/guides/bun/index.mdx | 2 +- .../javascript/guides/capacitor/index.mdx | 2 +- .../javascript/guides/deno/index.mdx | 2 +- .../javascript/guides/effect/index.mdx | 6 ++--- .../javascript/guides/electron/index.mdx | 2 +- .../javascript/guides/elysia/index.mdx | 2 +- .../javascript/guides/ember/index.mdx | 4 ++-- .../javascript/guides/firebase/index.mdx | 2 +- .../javascript/guides/gatsby/index.mdx | 4 ++-- .../javascript/guides/gcp-functions/index.mdx | 2 +- .../javascript/guides/hono/index.mdx | 8 +++---- .../javascript/guides/nuxt/index.mdx | 2 +- .../guides/react-router/manual-setup.mdx | 2 +- .../javascript/guides/remix/index.mdx | 2 +- .../javascript/guides/solid/index.mdx | 4 ++-- .../javascript/guides/solidstart/index.mdx | 2 +- .../javascript/guides/svelte/index.mdx | 4 ++-- .../platforms/javascript/guides/vue/index.mdx | 4 ++-- .../javascript.astro.mdx | 2 +- .../getting-started-complete/javascript.mdx | 4 ++-- .../javascript.nuxt.mdx | 2 +- .../javascript.remix.mdx | 2 +- .../getting-started-node/javascript.mdx | 2 +- .../javascript.mdx | 19 ---------------- .../javascript.mdx | 16 +++++++++++++- .../javascript.mdx | 22 ------------------- .../getting-started-tunneling/javascript.mdx | 16 +++++++++++--- .../javascript.remix.mdx | 12 ---------- 31 files changed, 66 insertions(+), 95 deletions(-) delete mode 100644 platform-includes/getting-started-sourcemaps-short-version-splitlayout/javascript.mdx delete mode 100644 platform-includes/getting-started-tunneling-splitlayout/javascript.mdx delete mode 100644 platform-includes/getting-started-tunneling/javascript.remix.mdx diff --git a/docs/platforms/javascript/guides/angular/index.mdx b/docs/platforms/javascript/guides/angular/index.mdx index b75ca585cbcb0..361a61a416e86 100644 --- a/docs/platforms/javascript/guides/angular/index.mdx +++ b/docs/platforms/javascript/guides/angular/index.mdx @@ -61,7 +61,7 @@ Prefer to set things up yourself? Check out the [Manual Setup](/platforms/javasc ## Avoid Ad Blockers With Tunneling (Optional) - + ## Verify diff --git a/docs/platforms/javascript/guides/angular/manual-setup.mdx b/docs/platforms/javascript/guides/angular/manual-setup.mdx index ede1d75b22d88..4fcf64787b22d 100644 --- a/docs/platforms/javascript/guides/angular/manual-setup.mdx +++ b/docs/platforms/javascript/guides/angular/manual-setup.mdx @@ -382,11 +382,11 @@ export class AppModule { ### Add Readable Stack Traces With Source Maps (Optional) - + ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify diff --git a/docs/platforms/javascript/guides/azure-functions/index.mdx b/docs/platforms/javascript/guides/azure-functions/index.mdx index 9c3d01a1eae7a..847e0acce940b 100644 --- a/docs/platforms/javascript/guides/azure-functions/index.mdx +++ b/docs/platforms/javascript/guides/azure-functions/index.mdx @@ -135,7 +135,7 @@ module.exports = async function (context, req) { ### Add Readable Stack Traces With Source Maps (Optional) - + ## Step 4: Verify Your Setup diff --git a/docs/platforms/javascript/guides/bun/index.mdx b/docs/platforms/javascript/guides/bun/index.mdx index af477cfd65f08..827620391be55 100644 --- a/docs/platforms/javascript/guides/bun/index.mdx +++ b/docs/platforms/javascript/guides/bun/index.mdx @@ -114,7 +114,7 @@ bun --preload ./instrument.js app.js ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/capacitor/index.mdx b/docs/platforms/javascript/guides/capacitor/index.mdx index f1ae4bb1dde54..df1542fd96158 100644 --- a/docs/platforms/javascript/guides/capacitor/index.mdx +++ b/docs/platforms/javascript/guides/capacitor/index.mdx @@ -94,7 +94,7 @@ If you're using Angular, React, Vue, or Nuxt, make sure to forward the `init` me ### Add Readable Stack Traces With Source Maps (Optional) - + ### Provide Native Debug Information for iOS (Optional) diff --git a/docs/platforms/javascript/guides/deno/index.mdx b/docs/platforms/javascript/guides/deno/index.mdx index d513c2ccae9a6..815f6bfb82dba 100644 --- a/docs/platforms/javascript/guides/deno/index.mdx +++ b/docs/platforms/javascript/guides/deno/index.mdx @@ -133,7 +133,7 @@ deno run --allow-read=./src index.ts ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/effect/index.mdx b/docs/platforms/javascript/guides/effect/index.mdx index 593a0134729d4..8c349a6fe20fd 100644 --- a/docs/platforms/javascript/guides/effect/index.mdx +++ b/docs/platforms/javascript/guides/effect/index.mdx @@ -224,7 +224,7 @@ const SentryLive = Layer.mergeAll( // ___PRODUCT_OPTION_START___ metrics // Forward Effect metrics to Sentry - Sentry.SentryEffectMetricsLayer, + Sentry.SentryEffectMetricsLayer // ___PRODUCT_OPTION_END___ metrics ); @@ -268,7 +268,7 @@ const SentryLive = Layer.mergeAll( // ___PRODUCT_OPTION_START___ logs // Forward Effect logs to Sentry - Logger.layer([Sentry.SentryEffectLogger]), + Logger.layer([Sentry.SentryEffectLogger]) // ___PRODUCT_OPTION_END___ logs ); @@ -281,7 +281,7 @@ const MainLive = YourAppLayer.pipe(Layer.provide(SentryLive)); ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify diff --git a/docs/platforms/javascript/guides/electron/index.mdx b/docs/platforms/javascript/guides/electron/index.mdx index 38cd6da9fc96f..e64706ea2e1b7 100644 --- a/docs/platforms/javascript/guides/electron/index.mdx +++ b/docs/platforms/javascript/guides/electron/index.mdx @@ -264,7 +264,7 @@ init( ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/elysia/index.mdx b/docs/platforms/javascript/guides/elysia/index.mdx index 6802d97b8c00a..590589328d849 100644 --- a/docs/platforms/javascript/guides/elysia/index.mdx +++ b/docs/platforms/javascript/guides/elysia/index.mdx @@ -173,7 +173,7 @@ const app = Sentry.withElysia(new Elysia(), { ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/ember/index.mdx b/docs/platforms/javascript/guides/ember/index.mdx index cacc1c7e31755..dbdc9d572c33e 100644 --- a/docs/platforms/javascript/guides/ember/index.mdx +++ b/docs/platforms/javascript/guides/ember/index.mdx @@ -121,11 +121,11 @@ export default class App extends Application { ### Add Readable Stack Traces With Source Maps (Optional) - + ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/firebase/index.mdx b/docs/platforms/javascript/guides/firebase/index.mdx index 7173bd604a8cc..6e4bca3adf974 100644 --- a/docs/platforms/javascript/guides/firebase/index.mdx +++ b/docs/platforms/javascript/guides/firebase/index.mdx @@ -169,7 +169,7 @@ exports.onUserCreated = onDocumentCreated("users/{userId}", async (event) => { ### Add Readable Stack Traces With Source Maps (Optional) - + ## Step 4: Verify Your Setup diff --git a/docs/platforms/javascript/guides/gatsby/index.mdx b/docs/platforms/javascript/guides/gatsby/index.mdx index 69b9db6c56799..95d1b4af62b47 100644 --- a/docs/platforms/javascript/guides/gatsby/index.mdx +++ b/docs/platforms/javascript/guides/gatsby/index.mdx @@ -169,11 +169,11 @@ Sentry.init({ ### Add Readable Stack Traces With Source Maps (Optional) - + ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/gcp-functions/index.mdx b/docs/platforms/javascript/guides/gcp-functions/index.mdx index 5ab1cf4d32948..f58e0c1e8879a 100644 --- a/docs/platforms/javascript/guides/gcp-functions/index.mdx +++ b/docs/platforms/javascript/guides/gcp-functions/index.mdx @@ -71,7 +71,7 @@ Make sure to initialize Sentry at the top of your function code and wrap each fu ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/hono/index.mdx b/docs/platforms/javascript/guides/hono/index.mdx index 4e7e133fa9190..905d527a2c705 100644 --- a/docs/platforms/javascript/guides/hono/index.mdx +++ b/docs/platforms/javascript/guides/hono/index.mdx @@ -142,7 +142,7 @@ If you're deploying to Cloudflare Workers, set the `nodejs_compat` compatibility ```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} { - "compatibility_flags": ["nodejs_compat"] + "compatibility_flags": ["nodejs_compat"], } ``` @@ -271,7 +271,7 @@ app.use( // Enable logs to be sent to Sentry enableLogs: true, // ___PRODUCT_OPTION_END___ logs - }), + }) ); // Your routes here @@ -317,7 +317,7 @@ app.use( // Enable logs to be sent to Sentry enableLogs: true, // ___PRODUCT_OPTION_END___ logs - }), + }) ); // Your routes here @@ -365,7 +365,7 @@ By default, Sentry captures exceptions from Hono's `onError` handler, excluding ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/nuxt/index.mdx b/docs/platforms/javascript/guides/nuxt/index.mdx index c635f49352eb8..534c540af72b8 100644 --- a/docs/platforms/javascript/guides/nuxt/index.mdx +++ b/docs/platforms/javascript/guides/nuxt/index.mdx @@ -48,7 +48,7 @@ This guide assumes that you enable all features and allow the wizard to create a ## Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/react-router/manual-setup.mdx b/docs/platforms/javascript/guides/react-router/manual-setup.mdx index 36d201d67da7f..e3532cabdab35 100644 --- a/docs/platforms/javascript/guides/react-router/manual-setup.mdx +++ b/docs/platforms/javascript/guides/react-router/manual-setup.mdx @@ -572,7 +572,7 @@ export default { ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/remix/index.mdx b/docs/platforms/javascript/guides/remix/index.mdx index 1fe4222d21bfd..54820230628b2 100644 --- a/docs/platforms/javascript/guides/remix/index.mdx +++ b/docs/platforms/javascript/guides/remix/index.mdx @@ -104,7 +104,7 @@ export default withSentry(App); ## Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/solid/index.mdx b/docs/platforms/javascript/guides/solid/index.mdx index 3e12c01761273..ae389ca8693b1 100644 --- a/docs/platforms/javascript/guides/solid/index.mdx +++ b/docs/platforms/javascript/guides/solid/index.mdx @@ -162,11 +162,11 @@ To automatically report exceptions from inside a component tree to Sentry, wrap ### Add Readable Stack Traces With Source Maps (Optional) - + ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/solidstart/index.mdx b/docs/platforms/javascript/guides/solidstart/index.mdx index 672d36237d8d2..abff32a8a37a0 100644 --- a/docs/platforms/javascript/guides/solidstart/index.mdx +++ b/docs/platforms/javascript/guides/solidstart/index.mdx @@ -409,7 +409,7 @@ SENTRY_AUTH_TOKEN="___ORG_AUTH_TOKEN___" ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/svelte/index.mdx b/docs/platforms/javascript/guides/svelte/index.mdx index f80a14e98e75e..e8c587a92b3a3 100644 --- a/docs/platforms/javascript/guides/svelte/index.mdx +++ b/docs/platforms/javascript/guides/svelte/index.mdx @@ -195,11 +195,11 @@ export default app; ### Add Readable Stack Traces With Source Maps (Optional) - + ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/vue/index.mdx b/docs/platforms/javascript/guides/vue/index.mdx index 385f3bc807a2a..592cb92d7e3cc 100644 --- a/docs/platforms/javascript/guides/vue/index.mdx +++ b/docs/platforms/javascript/guides/vue/index.mdx @@ -265,11 +265,11 @@ pinia.use(createSentryPiniaPlugin()); ### Add Readable Stack Traces With Source Maps (Optional) - + ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/platform-includes/getting-started-complete/javascript.astro.mdx b/platform-includes/getting-started-complete/javascript.astro.mdx index c7f76751c5a64..381d6e5aa9d7f 100644 --- a/platform-includes/getting-started-complete/javascript.astro.mdx +++ b/platform-includes/getting-started-complete/javascript.astro.mdx @@ -437,7 +437,7 @@ SENTRY_AUTH_TOKEN=___ORG_AUTH_TOKEN___ ### Avoid Ad Blockers With Tunneling (Optional) - + diff --git a/platform-includes/getting-started-complete/javascript.mdx b/platform-includes/getting-started-complete/javascript.mdx index 567399d5c0017..9422d2c69976d 100644 --- a/platform-includes/getting-started-complete/javascript.mdx +++ b/platform-includes/getting-started-complete/javascript.mdx @@ -26,11 +26,11 @@ Choose the features you want to configure, and this guide will show you how: ### Add Readable Stack Traces With Source Maps (Optional) - + ### Avoid Ad Blockers With Tunneling (Optional) - + ## Verify Your Setup diff --git a/platform-includes/getting-started-complete/javascript.nuxt.mdx b/platform-includes/getting-started-complete/javascript.nuxt.mdx index 1478848ff70a2..3ce84f94da7c0 100644 --- a/platform-includes/getting-started-complete/javascript.nuxt.mdx +++ b/platform-includes/getting-started-complete/javascript.nuxt.mdx @@ -402,7 +402,7 @@ export default defineNuxtConfig({ ### Avoid Ad Blockers With Tunneling (Optional) diff --git a/platform-includes/getting-started-complete/javascript.remix.mdx b/platform-includes/getting-started-complete/javascript.remix.mdx index 7972b9f7f1cd2..1a7c0a4ec1833 100644 --- a/platform-includes/getting-started-complete/javascript.remix.mdx +++ b/platform-includes/getting-started-complete/javascript.remix.mdx @@ -434,7 +434,7 @@ SENTRY_AUTH_TOKEN=___ORG_AUTH_TOKEN___ ### Avoid Ad Blockers With Tunneling (Optional) - + diff --git a/platform-includes/getting-started-node/javascript.mdx b/platform-includes/getting-started-node/javascript.mdx index bac295402abad..1e748999b2395 100644 --- a/platform-includes/getting-started-node/javascript.mdx +++ b/platform-includes/getting-started-node/javascript.mdx @@ -103,7 +103,7 @@ node --import ./instrument.mjs app.mjs ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/platform-includes/getting-started-sourcemaps-short-version-splitlayout/javascript.mdx b/platform-includes/getting-started-sourcemaps-short-version-splitlayout/javascript.mdx deleted file mode 100644 index 528a817b14f05..0000000000000 --- a/platform-includes/getting-started-sourcemaps-short-version-splitlayout/javascript.mdx +++ /dev/null @@ -1,19 +0,0 @@ - - - - -The stack traces in your Sentry errors probably won't look like your actual code without unminifying them. To fix this, upload your source maps to Sentry. The easiest way to do this is by using the Sentry Wizard. - -Alternatively, take a look at our Uploading Source Maps documentation. - - - - - -```bash -npx @sentry/wizard@latest -i sourcemaps -``` - - - - diff --git a/platform-includes/getting-started-sourcemaps-short-version/javascript.mdx b/platform-includes/getting-started-sourcemaps-short-version/javascript.mdx index c4a623f7c0053..528a817b14f05 100644 --- a/platform-includes/getting-started-sourcemaps-short-version/javascript.mdx +++ b/platform-includes/getting-started-sourcemaps-short-version/javascript.mdx @@ -1,5 +1,19 @@ -The stack traces in your Sentry errors probably won't look like your actual code without unminifying them. To fix this, upload your source maps to Sentry. The easiest way to do this is by using the Sentry Wizard: + + + + +The stack traces in your Sentry errors probably won't look like your actual code without unminifying them. To fix this, upload your source maps to Sentry. The easiest way to do this is by using the Sentry Wizard. + +Alternatively, take a look at our Uploading Source Maps documentation. + + + + ```bash npx @sentry/wizard@latest -i sourcemaps ``` + + + + diff --git a/platform-includes/getting-started-tunneling-splitlayout/javascript.mdx b/platform-includes/getting-started-tunneling-splitlayout/javascript.mdx deleted file mode 100644 index 39962565e41c6..0000000000000 --- a/platform-includes/getting-started-tunneling-splitlayout/javascript.mdx +++ /dev/null @@ -1,22 +0,0 @@ - - - - -You can prevent ad blockers from blocking Sentry events using tunneling. Use the `tunnel` option in `Sentry.init` to add an API endpoint in your application that forwards Sentry events to Sentry servers. - -This will send all events to the `tunnel` endpoint. However, the events need to be parsed and redirected to Sentry, so you'll need to do additional configuration on the server. You can find a detailed explanation on how to do this on our Troubleshooting page. - - - - - -```javascript {3} -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tunnel: "/tunnel", -}); -``` - - - - diff --git a/platform-includes/getting-started-tunneling/javascript.mdx b/platform-includes/getting-started-tunneling/javascript.mdx index dc5897eee2945..39962565e41c6 100644 --- a/platform-includes/getting-started-tunneling/javascript.mdx +++ b/platform-includes/getting-started-tunneling/javascript.mdx @@ -1,6 +1,14 @@ -You can prevent ad blockers from blocking Sentry events using tunneling. Use the `tunnel` option to add an API endpoint in your application that forwards Sentry events to Sentry servers. + + + -To enable tunneling, update `Sentry.init` with the following option: +You can prevent ad blockers from blocking Sentry events using tunneling. Use the `tunnel` option in `Sentry.init` to add an API endpoint in your application that forwards Sentry events to Sentry servers. + +This will send all events to the `tunnel` endpoint. However, the events need to be parsed and redirected to Sentry, so you'll need to do additional configuration on the server. You can find a detailed explanation on how to do this on our Troubleshooting page. + + + + ```javascript {3} Sentry.init({ @@ -9,4 +17,6 @@ Sentry.init({ }); ``` -This will send all events to the `tunnel` endpoint. However, the events need to be parsed and redirected to Sentry, so you'll need to do additional configuration on the server. You can find a detailed explanation on how to do this on our Troubleshooting page. + + + diff --git a/platform-includes/getting-started-tunneling/javascript.remix.mdx b/platform-includes/getting-started-tunneling/javascript.remix.mdx deleted file mode 100644 index fbc57108a38b9..0000000000000 --- a/platform-includes/getting-started-tunneling/javascript.remix.mdx +++ /dev/null @@ -1,12 +0,0 @@ -You can prevent ad blockers from blocking Sentry events using tunneling. Use the `tunnel` option to add an API endpoint in your application that forwards Sentry events to Sentry servers. - -To enable tunneling, update `Sentry.init` in your `entry.client.tsx` file with the following option: - -```javascript {filename:entry.client.tsx}{3} -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tunnel: "/tunnel", -}); -``` - -This will send all events to the `tunnel` endpoint. However, the events need to be parsed and redirected to Sentry, so you'll need to do additional configuration on the server. You can find a detailed explanation on how to do this on our Troubleshooting page. From c84d25ea3cf2f3ba4eba945ae9587ba47923e397 Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Tue, 12 May 2026 13:52:02 +0200 Subject: [PATCH 04/12] finalize split layout include file cleanup --- .../javascript/guides/cloudflare/index.mdx | 4 +- .../javascript/guides/nestjs/index.mdx | 2 +- .../javascript.astro.mdx | 2 +- .../javascript.nuxt.mdx | 2 +- .../javascript.remix.mdx | 2 +- .../javascript.sveltekit.mdx | 2 +- .../javascript.cloudflare.mdx | 66 +++++++++++---- .../javascript.cloudflare.splitlayout.mdx | 84 ------------------- .../javascript.cloudflare.mdx | 20 +++++ 9 files changed, 77 insertions(+), 107 deletions(-) delete mode 100644 platform-includes/getting-started-config/javascript.cloudflare.splitlayout.mdx diff --git a/docs/platforms/javascript/guides/cloudflare/index.mdx b/docs/platforms/javascript/guides/cloudflare/index.mdx index 18c1b39f0c7e5..6dc8e7f126f75 100644 --- a/docs/platforms/javascript/guides/cloudflare/index.mdx +++ b/docs/platforms/javascript/guides/cloudflare/index.mdx @@ -63,7 +63,7 @@ The main Sentry configuration should happen as early as possible in your app's l ### Setup for Cloudflare Workers @@ -153,7 +153,7 @@ export const handle = ({ event, resolve }) => { ### Add Readable Stack Traces With Source Maps (Optional) - + ## Verify Your Setup diff --git a/docs/platforms/javascript/guides/nestjs/index.mdx b/docs/platforms/javascript/guides/nestjs/index.mdx index e0e858e8bba06..e05cf974e6e23 100644 --- a/docs/platforms/javascript/guides/nestjs/index.mdx +++ b/docs/platforms/javascript/guides/nestjs/index.mdx @@ -122,7 +122,7 @@ export class AppModule {} ### Add Readable Stack Traces With Source Maps (Optional) - + ## Capture Nest.js Errors diff --git a/platform-includes/getting-started-complete/javascript.astro.mdx b/platform-includes/getting-started-complete/javascript.astro.mdx index 381d6e5aa9d7f..2bbacf4c76d58 100644 --- a/platform-includes/getting-started-complete/javascript.astro.mdx +++ b/platform-includes/getting-started-complete/javascript.astro.mdx @@ -92,7 +92,7 @@ pnpm add @sentry/astro @sentry/cloudflare ### Register the Sentry Integration diff --git a/platform-includes/getting-started-complete/javascript.nuxt.mdx b/platform-includes/getting-started-complete/javascript.nuxt.mdx index 3ce84f94da7c0..c53e3a5c574cb 100644 --- a/platform-includes/getting-started-complete/javascript.nuxt.mdx +++ b/platform-includes/getting-started-complete/javascript.nuxt.mdx @@ -272,7 +272,7 @@ node --import ./.output/server/sentry.server.config.mjs .output/server/index.mjs #### Add the Nitro Plugin diff --git a/platform-includes/getting-started-complete/javascript.remix.mdx b/platform-includes/getting-started-complete/javascript.remix.mdx index 1a7c0a4ec1833..aeb5a07651852 100644 --- a/platform-includes/getting-started-complete/javascript.remix.mdx +++ b/platform-includes/getting-started-complete/javascript.remix.mdx @@ -358,7 +358,7 @@ export const handleError = Sentry.sentryHandleError; diff --git a/platform-includes/getting-started-complete/javascript.sveltekit.mdx b/platform-includes/getting-started-complete/javascript.sveltekit.mdx index dabf56b3f39d4..0a174684bb053 100644 --- a/platform-includes/getting-started-complete/javascript.sveltekit.mdx +++ b/platform-includes/getting-started-complete/javascript.sveltekit.mdx @@ -398,7 +398,7 @@ export default defineConfig({ diff --git a/platform-includes/getting-started-config/javascript.cloudflare.mdx b/platform-includes/getting-started-config/javascript.cloudflare.mdx index 7c3587f8138d2..b7d4c60aefa9f 100644 --- a/platform-includes/getting-started-config/javascript.cloudflare.mdx +++ b/platform-includes/getting-started-config/javascript.cloudflare.mdx @@ -1,5 +1,13 @@ + + + + Since the SDK needs access to the `AsyncLocalStorage` API, you need to set the `nodejs_compat` compatibility flag in your `wrangler.(jsonc|toml)` configuration file: + + + + ```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} { "compatibility_flags": ["nodejs_compat"], @@ -10,41 +18,67 @@ Since the SDK needs access to the `AsyncLocalStorage` API, you need to set the ` compatibility_flags = ["nodejs_compat"] ``` + + + + ### Release Configuration (Optional) + + + + If you don't set the `release` option manually, the SDK automatically detects it from these sources (in order of priority): 1. The `SENTRY_RELEASE` environment variable 2. The `CF_VERSION_METADATA.id` binding (if configured) -To enable automatic release detection via Cloudflare's version metadata, add the `CF_VERSION_METADATA` binding in your wrangler configuration. This provides access to the [Cloudflare version metadata](https://developers.cloudflare.com/workers/runtime-apis/bindings/version-metadata/): +To enable automatic release detection via Cloudflare's version metadata, add the `CF_VERSION_METADATA` binding in your wrangler configuration. This provides access to the [Cloudflare version metadata](https://developers.cloudflare.com/workers/runtime-apis/bindings/version-metadata/). + + + + + +```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} +{ + // ... + "version_metadata": { + "binding": "CF_VERSION_METADATA", + }, +} +``` + +```toml {tabTitle:Toml} {filename:wrangler.toml} +[version_metadata] +binding = "CF_VERSION_METADATA" +``` + + + + + + + + In earlier versions, you need to manually extract `CF_VERSION_METADATA.id` and pass it as the `release` option: + + + ```javascript Sentry.withSentry( (env) => ({ dsn: "___PUBLIC_DSN___", release: env.CF_VERSION_METADATA?.id, - }), + }) // ... ); ``` + + + - -```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} -{ - // ... - "version_metadata": { - "binding": "CF_VERSION_METADATA" - } -} -``` - -```toml {tabTitle:Toml} {filename:wrangler.toml} -[version_metadata] -binding = "CF_VERSION_METADATA" -``` diff --git a/platform-includes/getting-started-config/javascript.cloudflare.splitlayout.mdx b/platform-includes/getting-started-config/javascript.cloudflare.splitlayout.mdx deleted file mode 100644 index b7d4c60aefa9f..0000000000000 --- a/platform-includes/getting-started-config/javascript.cloudflare.splitlayout.mdx +++ /dev/null @@ -1,84 +0,0 @@ - - - - -Since the SDK needs access to the `AsyncLocalStorage` API, you need to set the `nodejs_compat` compatibility flag in your `wrangler.(jsonc|toml)` configuration file: - - - - - -```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} -{ - "compatibility_flags": ["nodejs_compat"], -} -``` - -```toml {tabTitle:Toml} {filename:wrangler.toml} -compatibility_flags = ["nodejs_compat"] -``` - - - - - -### Release Configuration (Optional) - - - - - -If you don't set the `release` option manually, the SDK automatically detects it from these sources (in order of priority): - -1. The `SENTRY_RELEASE` environment variable -2. The `CF_VERSION_METADATA.id` binding (if configured) - -To enable automatic release detection via Cloudflare's version metadata, add the `CF_VERSION_METADATA` binding in your wrangler configuration. This provides access to the [Cloudflare version metadata](https://developers.cloudflare.com/workers/runtime-apis/bindings/version-metadata/). - - - - - -```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} -{ - // ... - "version_metadata": { - "binding": "CF_VERSION_METADATA", - }, -} -``` - -```toml {tabTitle:Toml} {filename:wrangler.toml} -[version_metadata] -binding = "CF_VERSION_METADATA" -``` - - - - - - - - - - - -In earlier versions, you need to manually extract `CF_VERSION_METADATA.id` and pass it as the `release` option: - - - - -```javascript -Sentry.withSentry( - (env) => ({ - dsn: "___PUBLIC_DSN___", - release: env.CF_VERSION_METADATA?.id, - }) - // ... -); -``` - - - - - diff --git a/platform-includes/getting-started-sourcemaps-short-version/javascript.cloudflare.mdx b/platform-includes/getting-started-sourcemaps-short-version/javascript.cloudflare.mdx index 64b5ba5b3c928..d8757881bde56 100644 --- a/platform-includes/getting-started-sourcemaps-short-version/javascript.cloudflare.mdx +++ b/platform-includes/getting-started-sourcemaps-short-version/javascript.cloudflare.mdx @@ -1,7 +1,14 @@ + + + + The stack traces in your Sentry errors probably won't look like your actual code without unminifying them. To fix this, upload your source maps to Sentry. First, set the `upload_source_maps` option to `true` in your `wrangler.(jsonc|toml)` config file to enable source map uploading: + + + ```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} { "upload_source_maps": true, @@ -12,8 +19,21 @@ First, set the `upload_source_maps` option to `true` in your `wrangler.(jsonc|to upload_source_maps = true ``` + + + + + + Next, run the Sentry Wizard to finish your setup: + + + ```bash npx @sentry/wizard@latest -i sourcemaps ``` + + + + From 9b703d3707649a6eb6908830d200e516564de06a Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Thu, 21 May 2026 13:17:53 +0200 Subject: [PATCH 05/12] create New Spans guide for JS SDKs --- .../common/tracing/new-spans/index.mdx | 365 ++++++++++++++++++ .../node/tracing/stream-spans/index.mdx | 232 ----------- .../enable-stream-mode/javascript.astro.mdx | 1 + .../enable-stream-mode/javascript.bun.mdx | 24 ++ .../enable-stream-mode/javascript.deno.mdx | 23 ++ .../javascript.electron.mdx | 51 +++ .../enable-stream-mode/javascript.ember.mdx | 27 ++ .../javascript.gcp-functions.mdx | 24 ++ .../enable-stream-mode/javascript.hono.mdx | 48 +++ .../enable-stream-mode/javascript.mdx | 28 ++ .../enable-stream-mode/javascript.nestjs.mdx | 24 ++ .../enable-stream-mode/javascript.nextjs.mdx | 24 ++ .../enable-stream-mode/javascript.nitro.mdx | 24 ++ .../enable-stream-mode/javascript.node.mdx | 34 ++ .../enable-stream-mode/javascript.nuxt.mdx | 49 +++ .../javascript.react-router.mdx | 50 +++ .../enable-stream-mode/javascript.remix.mdx | 50 +++ .../enable-stream-mode/javascript.solid.mdx | 28 ++ .../javascript.solidstart.mdx | 51 +++ .../javascript.sveltekit.mdx | 51 +++ .../javascript.tanstackstart-react.mdx | 50 +++ .../enable-stream-mode/javascript.wasm.mdx | 30 ++ 22 files changed, 1056 insertions(+), 232 deletions(-) create mode 100644 docs/platforms/javascript/common/tracing/new-spans/index.mdx delete mode 100644 docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.astro.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.bun.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.deno.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.electron.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.ember.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.hono.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.nitro.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.node.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.nuxt.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.react-router.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.remix.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.solid.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.sveltekit.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.wasm.mdx diff --git a/docs/platforms/javascript/common/tracing/new-spans/index.mdx b/docs/platforms/javascript/common/tracing/new-spans/index.mdx new file mode 100644 index 0000000000000..4c7358afcb41c --- /dev/null +++ b/docs/platforms/javascript/common/tracing/new-spans/index.mdx @@ -0,0 +1,365 @@ +--- +title: New Spans +description: "Learn how to use stream mode to send spans to Sentry as they finish, removing the 1,000-span limit and making trace data visible sooner." +sidebar_order: 35 +new: true +notSupported: + - javascript.cordova + - javascript.effect + - javascript.elysia +--- + + + +By default, the Sentry JavaScript SDKs collect all spans in memory and send them to Sentry as a single transaction once the root span ends. This is called transaction mode. +Stream mode changes this by sending spans to Sentry in batches as they finish. + + + +- **No 1,000-span limit.** In transaction mode, transactions are capped at 1,000 spans. Stream mode has no upper limit since spans are sent in batches. +- **Lower memory usage.** Spans are flushed periodically and don't need to be held in memory until the root span ends. This is especially useful for long-running processes like queue consumers or cron jobs. +- **Faster visibility.** Span data arrives in Sentry as your application runs, instead of only after the entire operation completes. +- **No data loss from crashes.** If your process terminates unexpectedly, spans that were already flushed are preserved. In transaction mode, a crash before the root span ends means all span data is lost. + + + +## Prerequisites + +You need: + +- Tracing configured in + your app +- Sentry SDK `>=10.53.1` + +## Migrate from Transaction Mode + +For most users, switching to stream mode requires no code changes beyond the initial opt-in. If you use `beforeSendSpan` or `beforeSendTransaction`, follow these steps: + +1. [Enable stream mode](#enable-stream-mode) +2. [Wrap `beforeSendSpan` with `Sentry.withStreamedSpan()` to filter spans](#filter-spans) +3. [Replace `beforeSendTransaction` with `ignoreSpans` to drop spans](#drop-spans) +4. [Verify the migration](#verify-your-setup) + +## Enable Stream Mode + + + + + + + +Tracing modes are scoped per SDK, which means you can use, for example, stream mode in your frontend, and transaction mode in your backend, or vice versa. + + + + + + + +When stream mode is enabled, the SDK maintains an internal buffer that groups spans by trace ID. + +Spans are flushed: + +- On a regular interval (every 5 seconds by default). +- When a trace's buffer reaches 1,000 spans. +- When you call `Sentry.flush()` or `Sentry.close()`. + +Each flush sends only the spans accumulated since the last flush, grouped into envelopes by trace ID. + + + +## Manual Instrumentation (Optional) + +### Start a Span + + + + + +Use `Sentry.startSpan()` to create a span that is automatically ended when the callback completes: + + + + +```javascript +const result = await Sentry.startSpan( + { name: "my-operation", attributes: { "my.attribute": "value" } }, + async () => { + // Your code here + return await doWork(); + } +); +``` + + + + + + + +Child spans created inside the callback are automatically associated with the parent: + + + + +```javascript +await Sentry.startSpan({ name: "parent-operation" }, async () => { + await Sentry.startSpan({ name: "child-step-1" }, async () => { + await stepOne(); + }); + + await Sentry.startSpan({ name: "child-step-2" }, async () => { + await stepTwo(); + }); +}); +``` + + + + + +For more details on span creation APIs, such as `startSpan`, `startSpanManual`, or `startInactiveSpan`, see Instrumentation. + +### Add Span Attributes + +Attach structured metadata to spans using attributes, which can be `string`, `number`, or `boolean`, as well as arrays of these types. + + + + + +You can set attributes when starting a span: + + + + +```javascript +Sentry.startSpan( + { + name: "process-order", + op: "queue.process", + attributes: { + "order.id": "abc-123", + "order.item_count": 5, + "order.priority": true, + }, + }, + () => { + // Process the order + } +); +``` + + + + + + + +Or add them to an already running span: + + + + +```javascript +Sentry.startSpan({ name: "handle-request" }, (span) => { + // Set a single attribute + span.setAttribute("http.response.status_code", 200); + + // Set multiple attributes at once + span.setAttributes({ + "http.route": "/api/users", + "user.id": "user-42", + }); +}); +``` + + + + + +## Distributed Tracing (Optional) + +Distributed tracing works out of the box when tracing is enabled and works the same way in stream mode. If you need to manually propagate trace context, for example, +when the SDK can't instrument automatically, see Custom Trace Propagation. + +## Extended Configuration (Optional) + +### Filter Spans + + + + + +To modify or redact span data before it's sent, use `beforeSendSpan`. In stream mode, wrap it with `Sentry.withStreamedSpan()` so the SDK applies it to spans as they are +flushed rather than only at transaction time. + + + `beforeSendSpan` can only modify span data and you cannot use it to drop + spans. Use [`ignoreSpans`](#drop-spans) instead. + + + + + + + +```JavaScript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", + beforeSendSpan: Sentry.withStreamedSpan((span) => { + if (span.op === "db.query") { + span.description = "[filtered]"; + } + return span; + }), +}); +``` + + + + + + + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + // other integrations + Sentry.spanStreamingIntegration(), + ], + beforeSendSpan: Sentry.withStreamedSpan((span) => { + if (span.op === "db.query") { + span.description = "[filtered]"; + } + return span; + }), +}); +``` + + + + + + + + + + +If you're using `beforeSendSpan`, wrap it with `Sentry.withStreamedSpan()` as shown above, otherwise the SDK falls back to transaction mode. The span object also has +different property names in stream mode; see `beforeSendSpan` for the full reference. + +If you're using `beforeSendTransaction` to drop spans, use [`ignoreSpans`](#drop-spans) instead, since `beforeSendTransaction` is not available in stream mode. + + + +### Drop Spans + + + + + +To prevent specific spans from being created, use the `ignoreSpans` option: + + + + + + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", + ignoreSpans: [ + // Drop spans whose name contains "healthcheck" + "healthcheck", + // Drop spans whose name matches a pattern + /^GET \/api\/v1\/internal/, + // Drop spans matching name and attribute conditions + { + name: /^GET \//, + attributes: { + "http.response.status_code": 200, + "http.route": "/api/status", + }, + }, + ], +}); +``` + + + + + + + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + // other integrations + Sentry.spanStreamingIntegration(), + ], + ignoreSpans: [ + // Drop spans whose name contains "healthcheck" + "healthcheck", + // Drop spans whose name matches a pattern + /^GET \/api\/v1\/internal/, + // Drop spans matching name and attribute conditions + { + name: /^GET \//, + attributes: { + "http.response.status_code": 200, + "http.route": "/api/status", + }, + }, + ], +}); +``` + + + + + + + + + +If a matching span is a root span, all of its child spans are dropped as well. If a child span matches, only that span is dropped and its children are reparented to the nearest ancestor. + +In stream mode, `ignoreSpans` is evaluated before a span is created, so only the span name and attributes available at that point are taken into account. + + + +In transaction mode, `ignoreSpans` is evaluated at root span end rather than before span creation. Review your existing rules to make sure the attributes you're matching on are passed when the span is created. + + + +## Verify Your Setup + +To make sure you've enabled stream mode successfully: + + + + + +- **Check the Sentry dashboard**: Spans should appear in the Traces view shortly after they complete. Traces look the same as in transaction mode, but without transactions. +- **Check for fallback warnings in your logs**: If the SDK logs warnings about falling back to transaction mode, your `beforeSendSpan` callback is likely missing the `Sentry.withStreamedSpan()` wrapper. + + + + + + + +- **Check the Sentry dashboard**: Spans should appear in the Traces view shortly after they complete. Traces look the same as in transaction mode, but without transactions. +- **Check for fallback warnings in your logs**: If the SDK logs warnings about falling back to transaction mode, your `beforeSendSpan` callback is likely missing the `Sentry.withStreamedSpan()` wrapper. +- **Check the network tab in your browser's DevTools**: Span envelopes should appear as individual requests with content type `application/vnd.sentry.items.span.v2+json` + + diff --git a/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx b/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx deleted file mode 100644 index 6f0c35973ca37..0000000000000 --- a/docs/platforms/javascript/guides/node/tracing/stream-spans/index.mdx +++ /dev/null @@ -1,232 +0,0 @@ ---- -title: Stream Spans -description: "Learn how to use streamed spans to remove the 1000 span limit, reduce memory usage, and get faster visibility into your traces." -sidebar_order: 50 -new: true ---- - -By default, the Sentry Node.js SDK collects all spans in memory and sends them as a single transaction once the root span ends. Streamed spans change this model: spans are sent incrementally in batches as they finish, rather than waiting for the entire transaction to complete. - -## Why Use Streamed Spans - -- **No 1000 span limit.** Transactions are capped at 1000 spans. With streamed spans, there is no upper limit since spans are sent in batches. -- **Lower memory usage.** Spans are flushed periodically and don't need to be held in memory until the root span ends. This is especially useful for long-running processes like queue consumers or cron jobs. -- **Faster visibility.** Span data arrives in Sentry as your application runs, instead of only after the entire operation completes. -- **No data loss from crashes.** If your process terminates unexpectedly, spans that were already flushed are preserved. With transactions, a crash before the root span ends means all span data is lost. - -## Enable Streamed Spans - -Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: - -```javascript {filename:instrument.js} -const Sentry = require("@sentry/node"); - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, - traceLifecycle: "stream", -}); -``` - -When `traceLifecycle` is set to `'static'` (the default), traces are sent as transactions. Setting it to `'stream'` enables span streaming. - -## Start a Span - -Starting spans works the same way as with transactions. Use `Sentry.startSpan()` to create a span that is automatically ended when the callback completes: - -```javascript -const result = await Sentry.startSpan( - { name: "my-operation", attributes: { "my.attribute": "value" } }, - async () => { - // Your code here - return await doWork(); - } -); -``` - -Child spans created inside the callback are automatically associated with the parent: - -```javascript -await Sentry.startSpan({ name: "parent-operation" }, async () => { - await Sentry.startSpan({ name: "child-step-1" }, async () => { - await stepOne(); - }); - - await Sentry.startSpan({ name: "child-step-2" }, async () => { - await stepTwo(); - }); -}); -``` - -With streaming enabled, each span is flushed to Sentry shortly after it ends instead of being held until the parent completes. - -For more details on span creation APIs (`startSpan`, `startSpanManual`, `startInactiveSpan`), see Instrumentation. - -## Attach Attributes - -Attributes let you attach structured metadata to spans. You can set them when starting a span: - -```javascript -Sentry.startSpan( - { - name: "process-order", - op: "queue.process", - attributes: { - "order.id": "abc-123", - "order.item_count": 5, - "order.priority": true, - }, - }, - () => { - // Process the order - } -); -``` - -Or add them to an already running span: - -```javascript -Sentry.startSpan({ name: "handle-request" }, (span) => { - // Set a single attribute - span.setAttribute("http.response.status_code", 200); - - // Set multiple attributes at once - span.setAttributes({ - "http.route": "/api/users", - "user.id": "user-42", - }); -}); -``` - -Attribute values can be `string`, `number`, or `boolean`, as well as arrays of these types. - -## Continue a Trace - -When you receive a request from an upstream service that includes Sentry trace headers, use `Sentry.continueTrace()` to connect your spans to the existing distributed trace: - -```javascript {filename:server.js} -const http = require("http"); -const Sentry = require("@sentry/node"); - -http.createServer((req, res) => { - Sentry.continueTrace( - { - sentryTrace: req.headers["sentry-trace"], - baggage: req.headers["baggage"], - }, - () => { - Sentry.startSpan({ name: `${req.method} ${req.url}` }, () => { - // Handle the request - res.end("OK"); - }); - } - ); -}); -``` - -To propagate the trace to downstream services, inject the trace headers into your outgoing requests: - -```javascript -await Sentry.startSpan({ name: "call-downstream" }, async () => { - const traceData = Sentry.getTraceData(); - - await fetch("https://downstream.example.com/api", { - headers: { - "sentry-trace": traceData["sentry-trace"], - baggage: traceData["baggage"], - }, - }); -}); -``` - -## Start a New Trace - -If you need to start a completely new trace that is not connected to the current one, use `Sentry.startNewTrace()`. This is useful for background jobs or scheduled tasks where you want a clean trace boundary: - -```javascript {filename:worker.js} -const Sentry = require("@sentry/node"); - -function processJob(job) { - Sentry.startNewTrace(() => { - Sentry.startSpan( - { - name: "process-job", - attributes: { "job.id": job.id, "job.type": job.type }, - }, - async () => { - await job.execute(); - } - ); - }); -} -``` - -Any spans created inside the `startNewTrace` callback belong to a fresh trace with a new trace ID. Once the callback ends, the SDK continues the previous trace (if one was active). - -## Scrub Span Data - -To modify or redact data on spans before they are sent, use `beforeSendSpan`. When using streamed spans, the hook must be wrapped with `Sentry.withStreamedSpan()` so the SDK applies it to spans as they are flushed rather than only at transaction time. - -If you don't have a `beforeSendSpan` hook, no extra setup is needed. - -```javascript {filename:instrument.js} -const Sentry = require("@sentry/node"); - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, - traceLifecycle: "stream", - beforeSendSpan: Sentry.withStreamedSpan((span) => { - if (span.op === "db.query") { - span.description = "[filtered]"; - } - return span; - }), -}); -``` - -Without the wrapper, `beforeSendSpan` is silently skipped for streamed spans. - -`beforeSendSpan` can only modify span data — you cannot use it to drop spans. To prevent spans from being created entirely, use [`ignoreSpans`](#drop-spans-with-ignorespans) instead. - -### Drop Spans With `ignoreSpans` - -To prevent specific spans from being created, use the `ignoreSpans` option. Unlike `beforeSendSpan` (which can only modify spans), `ignoreSpans` drops matching spans before they start. You can match by span name using strings or regular expressions, or use an object to also match on span attributes: - -```javascript {filename:instrument.js} -const Sentry = require("@sentry/node"); - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, - traceLifecycle: "stream", - ignoreSpans: [ - // Drop spans whose name contains "healthcheck" - "healthcheck", - // Drop spans whose name matches a pattern - /^GET \/api\/v1\/internal/, - // Drop spans matching name and attribute conditions - { - name: /^GET \//, - attributes: { - "http.response.status_code": 200, - "http.route": "/api/status", - }, - }, - ], -}); -``` - -If a matching span is a root span, all of its child spans are dropped as well. If a child span matches, only that span is dropped and its children are reparented to the next ancestor. - -If you need to redact or modify data on spans that aren't dropped, use [`beforeSendSpan`](#scrub-span-data) instead. - -## How Span Flushing Works - -When span streaming is enabled, the SDK maintains an internal buffer that groups spans by trace ID. Spans are flushed: - -- On a regular interval (every 5 seconds by default). -- When a trace's buffer reaches 1000 spans. -- When you call `Sentry.flush()` or `Sentry.close()`. - -Each flush sends only the spans that have accumulated since the last flush, grouped into envelopes by trace ID. diff --git a/platform-includes/performance/enable-stream-mode/javascript.astro.mdx b/platform-includes/performance/enable-stream-mode/javascript.astro.mdx new file mode 100644 index 0000000000000..e337d1625c6e6 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.astro.mdx @@ -0,0 +1 @@ +How? diff --git a/platform-includes/performance/enable-stream-mode/javascript.bun.mdx b/platform-includes/performance/enable-stream-mode/javascript.bun.mdx new file mode 100644 index 0000000000000..88a89d9a2cbad --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.bun.mdx @@ -0,0 +1,24 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {filename: instrument.js} +import * as Sentry from "@sentry/bun"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.deno.mdx b/platform-includes/performance/enable-stream-mode/javascript.deno.mdx new file mode 100644 index 0000000000000..f97f4a3b8fe6e --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.deno.mdx @@ -0,0 +1,23 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {filename: main.ts} +import * as Sentry from "npm:@sentry/deno"; +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.electron.mdx b/platform-includes/performance/enable-stream-mode/javascript.electron.mdx new file mode 100644 index 0000000000000..bfff939ee024d --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.electron.mdx @@ -0,0 +1,51 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your renderer: + + + + +```javascript +import * as Sentry from "@sentry/electron/renderer"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.browserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your main process: + + + + +```javascript +import * as Sentry from "@sentry/electron/main"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", + integrations: [Sentry.startupTracingIntegration()], +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.ember.mdx b/platform-includes/performance/enable-stream-mode/javascript.ember.mdx new file mode 100644 index 0000000000000..a929e63209df0 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.ember.mdx @@ -0,0 +1,27 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK: + + + + +```javascript +import * as Sentry from "@sentry/ember"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + +To revert to transaction mode, remove `spanStreamingIntegration()` from your integrations. diff --git a/platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx b/platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx new file mode 100644 index 0000000000000..8e79992c6f245 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx @@ -0,0 +1,24 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript +const Sentry = require("@sentry/google-cloud-serverless"); + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.hono.mdx b/platform-includes/performance/enable-stream-mode/javascript.hono.mdx new file mode 100644 index 0000000000000..00e86a73ca176 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.hono.mdx @@ -0,0 +1,48 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {tabTitle:Cloudflare Workers} +import { sentry } from "@sentry/hono/cloudflare"; + +app.use( + sentry(app, { + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", + }) +); +``` + +```javascript {tabTitle:Node.js} {filename: instrument.mjs} +import * as Sentry from "@sentry/hono/node"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + +```javascript {tabTitle:Bun} +import { sentry } from "@sentry/hono/bun"; + +app.use( + sentry(app, { + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", + }) +); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.mdx b/platform-includes/performance/enable-stream-mode/javascript.mdx new file mode 100644 index 0000000000000..629a63f20a357 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.mdx @@ -0,0 +1,28 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK: + + + + +```javascript +import * as Sentry from "___SDK_PACKAGE___"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.browserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + +To revert to transaction mode, remove `spanStreamingIntegration()` from your integrations. diff --git a/platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx b/platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx new file mode 100644 index 0000000000000..37d42e85e47c2 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx @@ -0,0 +1,24 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {filename: instrument.ts} +import * as Sentry from "@sentry/nestjs"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx b/platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx new file mode 100644 index 0000000000000..8b24032d52f12 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx @@ -0,0 +1,24 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK in your server, client, and edge config files: + + + + +```javascript +import * as Sentry from "@sentry/nextjs"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.nitro.mdx b/platform-includes/performance/enable-stream-mode/javascript.nitro.mdx new file mode 100644 index 0000000000000..95353de7136d2 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.nitro.mdx @@ -0,0 +1,24 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {filename: instrument.mjs} +import * as Sentry from "@sentry/nitro"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.node.mdx b/platform-includes/performance/enable-stream-mode/javascript.node.mdx new file mode 100644 index 0000000000000..cc27709b7d3d9 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.node.mdx @@ -0,0 +1,34 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {tabTitle:CommonJS} {filename: instrument.js} +const Sentry = require("@sentry/node"); + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + +```javascript {tabTitle:ESM} {filename: instrument.mjs} +import * as Sentry from "@sentry/node"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.nuxt.mdx b/platform-includes/performance/enable-stream-mode/javascript.nuxt.mdx new file mode 100644 index 0000000000000..b028e799accfc --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.nuxt.mdx @@ -0,0 +1,49 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your Sentry client config file: + + + + +```javascript {filename: sentry.client.config.ts} +import * as Sentry from "@sentry/nuxt"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your Sentry server config file: + + + + +```javascript {filename: sentry.server.config.ts} +import * as Sentry from "@sentry/nuxt"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.react-router.mdx b/platform-includes/performance/enable-stream-mode/javascript.react-router.mdx new file mode 100644 index 0000000000000..0c5464f34222d --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.react-router.mdx @@ -0,0 +1,50 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your `entry.client.tsx` file: + + + + +```javascript {filename: entry.client.tsx} +import * as Sentry from "@sentry/react-router"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.reactRouterTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your `instrument.server.mjs` file: + + + + +```javascript {filename: instrument.server.mjs} +import * as Sentry from "@sentry/react-router"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.remix.mdx b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx new file mode 100644 index 0000000000000..c379a04331c3b --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx @@ -0,0 +1,50 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your `entry.client.tsx` file: + + + + +```javascript {filename: entry.client.tsx} +import * as Sentry from "@sentry/remix"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.reactRouterTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your `instrument.server.mjs` file: + + + + +```javascript {filename: instrument.server.mjs} +import * as Sentry from "@sentry/remix"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.solid.mdx b/platform-includes/performance/enable-stream-mode/javascript.solid.mdx new file mode 100644 index 0000000000000..ce012824cbe2c --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.solid.mdx @@ -0,0 +1,28 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK: + + + + +```javascript {filename: index.jsx} +import * as Sentry from "@sentry/solid"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + solidRouterBrowserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + +To revert to transaction mode, remove `spanStreamingIntegration()` from your integrations. diff --git a/platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx b/platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx new file mode 100644 index 0000000000000..19c5a44affcb4 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx @@ -0,0 +1,51 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your `entry.client.tsx` file: + + + + +```javascript {filename: src/entry-client.tsx} +import * as Sentry from "@sentry/solidstart"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + // only add solidRouterBrowserTracingIntegration if you're using Solid Router + solidRouterBrowserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your `instrument.server.mjs` file: + + + + +```javascript {filename: src/instrument.server.mjs} +import * as Sentry from "@sentry/solidstart"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.sveltekit.mdx b/platform-includes/performance/enable-stream-mode/javascript.sveltekit.mdx new file mode 100644 index 0000000000000..24151e5689752 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.sveltekit.mdx @@ -0,0 +1,51 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your client hook file: + + + + +```javascript {filename: src/hooks.client.(js|ts)} +import * as Sentry from "@sentry/sveltekit"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your server instrumentation file: + +Requires SvelteKit `2.31.0` or higher. + + + + +```javascript {filename: src/instrumentation.server.(js|ts)} +import * as Sentry from "@sentry/sveltekit"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx b/platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx new file mode 100644 index 0000000000000..883990e3ae31d --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx @@ -0,0 +1,50 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your `router.tsx` file: + + + + +```javascript {filename: src/router.tsx} +import * as Sentry from "@sentry/tanstackstart-react"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.tanstackRouterBrowserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your `instrument.server.mjs` file: + + + + +```javascript {filename: instrument.server.mjs} +import * as Sentry from "@sentry/tanstackstart-react"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.wasm.mdx b/platform-includes/performance/enable-stream-mode/javascript.wasm.mdx new file mode 100644 index 0000000000000..78bd1c131b44b --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.wasm.mdx @@ -0,0 +1,30 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK: + + + + +```javascript +import * as Sentry from "@sentry/browser"; +import { wasmIntegration } from "@sentry/wasm"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.browserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + wasmIntegration(), + ], +}); +``` + + + + + +To revert to transaction mode, remove `spanStreamingIntegration()` from your integrations. From 4865de9c4fb82807153565b0cbc3163dfb7a5a2f Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Thu, 21 May 2026 14:22:02 +0200 Subject: [PATCH 06/12] update sdk snippets --- .../common/tracing/new-spans/index.mdx | 2 +- .../enable-stream-mode/javascript.astro.mdx | 51 ++++++++++++++++++- .../enable-stream-mode/javascript.remix.mdx | 2 +- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/docs/platforms/javascript/common/tracing/new-spans/index.mdx b/docs/platforms/javascript/common/tracing/new-spans/index.mdx index 4c7358afcb41c..693fc5bf7c9a7 100644 --- a/docs/platforms/javascript/common/tracing/new-spans/index.mdx +++ b/docs/platforms/javascript/common/tracing/new-spans/index.mdx @@ -27,7 +27,7 @@ Stream mode changes this by sending spans to Sentry in batches as they finish. You need: -- Tracing configured in +- Tracing configured in your app - Sentry SDK `>=10.53.1` diff --git a/platform-includes/performance/enable-stream-mode/javascript.astro.mdx b/platform-includes/performance/enable-stream-mode/javascript.astro.mdx index e337d1625c6e6..01c1d9dbda8d9 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.astro.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.astro.mdx @@ -1 +1,50 @@ -How? + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your Sentry client config file: + + + + +```javascript {filename: sentry.client.config.(ts|js)} +import * as Sentry from "@sentry/astro"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.browserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], +}); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your Sentry server config file: + + + + +```javascript {filename: sentry.server.config.(ts|js)} +import * as Sentry from "@sentry/astro"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.remix.mdx b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx index c379a04331c3b..e3e9d3a7b3f8f 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.remix.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx @@ -14,7 +14,7 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, integrations: [ - Sentry.reactRouterTracingIntegration(), + Sentry.browserTracingIntegration(), // enables stream mode Sentry.spanStreamingIntegration(), ], From 2f89f555d13211ac22b8ed589366048ae1fa305d Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Thu, 21 May 2026 16:20:35 +0200 Subject: [PATCH 07/12] update missing info and fix some snippets --- .../common/tracing/new-spans/index.mdx | 32 ++++++---- .../enable-stream-mode/javascript.bun.mdx | 1 + .../javascript.cloudflare.mdx | 62 +++++++++++++++++++ .../enable-stream-mode/javascript.deno.mdx | 1 + .../javascript.gcp-functions.mdx | 1 + .../enable-stream-mode/javascript.hono.mdx | 3 + .../enable-stream-mode/javascript.nestjs.mdx | 1 + .../enable-stream-mode/javascript.nextjs.mdx | 1 + .../enable-stream-mode/javascript.nitro.mdx | 1 + .../enable-stream-mode/javascript.node.mdx | 2 + .../enable-stream-mode/javascript.remix.mdx | 4 +- .../enable-stream-mode/javascript.solid.mdx | 2 + .../javascript.solidstart.mdx | 2 + .../javascript.tanstackstart-react.mdx | 28 ++++++--- 14 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 platform-includes/performance/enable-stream-mode/javascript.cloudflare.mdx diff --git a/docs/platforms/javascript/common/tracing/new-spans/index.mdx b/docs/platforms/javascript/common/tracing/new-spans/index.mdx index 693fc5bf7c9a7..dc048240f68dd 100644 --- a/docs/platforms/javascript/common/tracing/new-spans/index.mdx +++ b/docs/platforms/javascript/common/tracing/new-spans/index.mdx @@ -122,7 +122,7 @@ For more details on span creation APIs, such as `startSpan`, `startSpanManual`, ### Add Span Attributes -Attach structured metadata to spans using attributes, which can be `string`, `number`, or `boolean`, as well as arrays of these types. +Attach structured metadata to spans using `attributes`, which can be `string`, `number`, or `boolean`, as well as arrays of these types. @@ -176,6 +176,9 @@ Sentry.startSpan({ name: "handle-request" }, (span) => { + +Find more examples in our Sending Span Metrics documentation. + ## Distributed Tracing (Optional) @@ -191,11 +194,10 @@ when the SDK can't instrument automatically, see `beforeSendSpan`. In stream mode, wrap it with `Sentry.withStreamedSpan()` so the SDK applies it to spans as they are -flushed rather than only at transaction time. +To modify or redact span data before it's sent, use `beforeSendSpan`. In stream mode, wrap it with `Sentry.withStreamedSpan()` so the SDK applies it to spans as they are flushed rather than only at transaction time. - `beforeSendSpan` can only modify span data and you cannot use it to drop + `beforeSendSpan` can only modify span data, and you cannot use it to drop spans. Use [`ignoreSpans`](#drop-spans) instead. @@ -210,8 +212,10 @@ Sentry.init({ tracesSampleRate: 1.0, traceLifecycle: "stream", beforeSendSpan: Sentry.withStreamedSpan((span) => { - if (span.op === "db.query") { - span.description = "[filtered]"; + // In stream mode, 'op' is accessed via attributes + if (span.attributes?.["sentry.op"] === "db.query") { + // In stream mode, 'description' is now renamed to 'name' + span.name = "[filtered]"; } return span; }), @@ -233,8 +237,10 @@ Sentry.init({ Sentry.spanStreamingIntegration(), ], beforeSendSpan: Sentry.withStreamedSpan((span) => { - if (span.op === "db.query") { - span.description = "[filtered]"; + // In stream mode, 'op' is accessed via attributes + if (span.attributes?.["sentry.op"] === "db.query") { + // In stream mode, 'description' is now renamed to 'name' + span.name = "[filtered]"; } return span; }), @@ -250,8 +256,8 @@ Sentry.init({ -If you're using `beforeSendSpan`, wrap it with `Sentry.withStreamedSpan()` as shown above, otherwise the SDK falls back to transaction mode. The span object also has -different property names in stream mode; see `beforeSendSpan` for the full reference. +If you're using `beforeSendSpan`, wrap it with `Sentry.withStreamedSpan()` as shown above, otherwise the SDK falls back to transaction mode. +The callback signature and properties of the span object are also shaped differently. See `beforeSendSpan` for the full reference. If you're using `beforeSendTransaction` to drop spans, use [`ignoreSpans`](#drop-spans) instead, since `beforeSendTransaction` is not available in stream mode. @@ -333,11 +339,13 @@ Sentry.init({ If a matching span is a root span, all of its child spans are dropped as well. If a child span matches, only that span is dropped and its children are reparented to the nearest ancestor. -In stream mode, `ignoreSpans` is evaluated before a span is created, so only the span name and attributes available at that point are taken into account. +In stream mode, `ignoreSpans` is evaluated at span start, so only the span name and attributes available at that point are taken into account. Any name updates or additional attributes added while the span is active won't invluence whether the span is dropped. -In transaction mode, `ignoreSpans` is evaluated at root span end rather than before span creation. Review your existing rules to make sure the attributes you're matching on are passed when the span is created. +In transaction mode, `ignoreSpans` is evaluated at root span end rather than at span start. Review your existing rules to make sure the attributes you're matching on are passed when the span is created. + +If you're auto-instrumenting and don't know what the initial name of a span is when it starts, enable SDK debug logging during development by setting `debug: true` when initializing the SDK. diff --git a/platform-includes/performance/enable-stream-mode/javascript.bun.mdx b/platform-includes/performance/enable-stream-mode/javascript.bun.mdx index 88a89d9a2cbad..50fcd0d395b0d 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.bun.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.bun.mdx @@ -13,6 +13,7 @@ import * as Sentry from "@sentry/bun"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` diff --git a/platform-includes/performance/enable-stream-mode/javascript.cloudflare.mdx b/platform-includes/performance/enable-stream-mode/javascript.cloudflare.mdx new file mode 100644 index 0000000000000..baaa88c96e41c --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.cloudflare.mdx @@ -0,0 +1,62 @@ + + + +### Cloudflare Pages + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {filename: functions/_middleware.js} +import * as Sentry from "@sentry/cloudflare"; + +export const onRequest = [ + Sentry.sentryPagesPlugin((context) => ({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 0.2 + // enables stream mode + traceLifecycle: "stream", + })), +]; +``` + + + + + + +### Cloudflare Workers + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {filename: index.ts} +import * as Sentry from "@sentry/cloudflare"; + +export default Sentry.withSentry( + (env: Env) => ({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // Enables stream mode + traceLifecycle: "stream", + }), + { + async fetch(request, env, ctx) { + return new Response("Hello World!"); + }, + } satisfies ExportedHandler, +); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. diff --git a/platform-includes/performance/enable-stream-mode/javascript.deno.mdx b/platform-includes/performance/enable-stream-mode/javascript.deno.mdx index f97f4a3b8fe6e..297c972e1deaf 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.deno.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.deno.mdx @@ -12,6 +12,7 @@ import * as Sentry from "npm:@sentry/deno"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` diff --git a/platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx b/platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx index 8e79992c6f245..fc3c31c729469 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.gcp-functions.mdx @@ -13,6 +13,7 @@ const Sentry = require("@sentry/google-cloud-serverless"); Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` diff --git a/platform-includes/performance/enable-stream-mode/javascript.hono.mdx b/platform-includes/performance/enable-stream-mode/javascript.hono.mdx index 00e86a73ca176..951546caad069 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.hono.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.hono.mdx @@ -14,6 +14,7 @@ app.use( sentry(app, { dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }) ); @@ -25,6 +26,7 @@ import * as Sentry from "@sentry/hono/node"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` @@ -36,6 +38,7 @@ app.use( sentry(app, { dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }) ); diff --git a/platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx b/platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx index 37d42e85e47c2..8faa6f11ac1b2 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.nestjs.mdx @@ -13,6 +13,7 @@ import * as Sentry from "@sentry/nestjs"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` diff --git a/platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx b/platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx index 8b24032d52f12..99ba2c2facc47 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.nextjs.mdx @@ -13,6 +13,7 @@ import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` diff --git a/platform-includes/performance/enable-stream-mode/javascript.nitro.mdx b/platform-includes/performance/enable-stream-mode/javascript.nitro.mdx index 95353de7136d2..bf70f69d9b3cc 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.nitro.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.nitro.mdx @@ -13,6 +13,7 @@ import * as Sentry from "@sentry/nitro"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` diff --git a/platform-includes/performance/enable-stream-mode/javascript.node.mdx b/platform-includes/performance/enable-stream-mode/javascript.node.mdx index cc27709b7d3d9..053c862d60073 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.node.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.node.mdx @@ -13,6 +13,7 @@ const Sentry = require("@sentry/node"); Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` @@ -23,6 +24,7 @@ import * as Sentry from "@sentry/node"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, + // enables stream mode traceLifecycle: "stream", }); ``` diff --git a/platform-includes/performance/enable-stream-mode/javascript.remix.mdx b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx index e3e9d3a7b3f8f..24f62db05aa1f 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.remix.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx @@ -8,13 +8,15 @@ Opt in by adding `spanStreamingIntegration()` to your list of integrations when ```javascript {filename: entry.client.tsx} +import { useLocation, useMatches } from "@remix-run/react"; import * as Sentry from "@sentry/remix"; +import { useEffect } from "react"; Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, integrations: [ - Sentry.browserTracingIntegration(), + Sentry.browserTracingIntegration(useEffect, useLocation, useMatches), // enables stream mode Sentry.spanStreamingIntegration(), ], diff --git a/platform-includes/performance/enable-stream-mode/javascript.solid.mdx b/platform-includes/performance/enable-stream-mode/javascript.solid.mdx index ce012824cbe2c..3d9b1e178f852 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.solid.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.solid.mdx @@ -9,6 +9,8 @@ Opt in by adding `spanStreamingIntegration()` to your list of integrations when ```javascript {filename: index.jsx} import * as Sentry from "@sentry/solid"; +import { solidRouterBrowserTracingIntegration } from "@sentry/solid/solidrouter"; +import { render } from "solid-js/web"; Sentry.init({ dsn: "___PUBLIC_DSN___", diff --git a/platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx b/platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx index 19c5a44affcb4..a17c8b811ef3a 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.solidstart.mdx @@ -9,6 +9,8 @@ Opt in by adding `spanStreamingIntegration()` to your list of integrations when ```javascript {filename: src/entry-client.tsx} import * as Sentry from "@sentry/solidstart"; +// import solidRouterBrowserTracingIntegration if you're using Solid Router +import { solidRouterBrowserTracingIntegration } from "@sentry/solidstart/solidrouter"; Sentry.init({ dsn: "___PUBLIC_DSN___", diff --git a/platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx b/platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx index 883990e3ae31d..6253f20d44419 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.tanstackstart-react.mdx @@ -9,16 +9,24 @@ Opt in by adding `spanStreamingIntegration()` to your list of integrations when ```javascript {filename: src/router.tsx} import * as Sentry from "@sentry/tanstackstart-react"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, - integrations: [ - Sentry.tanstackRouterBrowserTracingIntegration(), - // enables stream mode - Sentry.spanStreamingIntegration(), - ], -}); +import { createRouter } from "@tanstack/react-router"; + +export const getRouter = () => { + const router = createRouter(); + + if (!router.isServer) { + Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.tanstackRouterBrowserTracingIntegration(router), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], + }); + } + return router; +}; ``` From 653aa8fd86760bb6a4d906fb7a55aebe0619e36a Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Thu, 21 May 2026 16:26:38 +0200 Subject: [PATCH 08/12] fix remix snippet --- .../performance/enable-stream-mode/javascript.remix.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform-includes/performance/enable-stream-mode/javascript.remix.mdx b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx index 24f62db05aa1f..1acc4d199bbed 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.remix.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.remix.mdx @@ -16,7 +16,11 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, integrations: [ - Sentry.browserTracingIntegration(useEffect, useLocation, useMatches), + Sentry.browserTracingIntegration({ + useEffect, + useLocation, + useMatches, + }), // enables stream mode Sentry.spanStreamingIntegration(), ], From 0b511d52106b120bee7b9737bae5e4d33f073f90 Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Fri, 22 May 2026 11:35:46 +0200 Subject: [PATCH 09/12] describe service spans --- docs/platforms/javascript/common/tracing/new-spans/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/tracing/new-spans/index.mdx b/docs/platforms/javascript/common/tracing/new-spans/index.mdx index dc048240f68dd..9fed7b058254e 100644 --- a/docs/platforms/javascript/common/tracing/new-spans/index.mdx +++ b/docs/platforms/javascript/common/tracing/new-spans/index.mdx @@ -12,7 +12,7 @@ notSupported: By default, the Sentry JavaScript SDKs collect all spans in memory and send them to Sentry as a single transaction once the root span ends. This is called transaction mode. -Stream mode changes this by sending spans to Sentry in batches as they finish. +Stream mode changes this by sending spans to Sentry in batches as they finish. Service spans, which represent a service's entry point, replace transactions as the main grouping for each service. From b8d68197de1bdf7814122df2b36403ecfde762a6 Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Fri, 22 May 2026 12:55:10 +0200 Subject: [PATCH 10/12] add effect and elysia --- .../common/tracing/new-spans/index.mdx | 10 ++- .../enable-stream-mode/javascript.effect.mdx | 61 +++++++++++++++++++ .../enable-stream-mode/javascript.elysia.mdx | 25 ++++++++ 3 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 platform-includes/performance/enable-stream-mode/javascript.effect.mdx create mode 100644 platform-includes/performance/enable-stream-mode/javascript.elysia.mdx diff --git a/docs/platforms/javascript/common/tracing/new-spans/index.mdx b/docs/platforms/javascript/common/tracing/new-spans/index.mdx index 9fed7b058254e..9b5c89e591553 100644 --- a/docs/platforms/javascript/common/tracing/new-spans/index.mdx +++ b/docs/platforms/javascript/common/tracing/new-spans/index.mdx @@ -5,8 +5,6 @@ sidebar_order: 35 new: true notSupported: - javascript.cordova - - javascript.effect - - javascript.elysia --- @@ -44,7 +42,7 @@ For most users, switching to stream mode requires no code changes beyond the ini - + @@ -226,7 +224,7 @@ Sentry.init({ - + ```javascript Sentry.init({ @@ -302,7 +300,7 @@ Sentry.init({ - + ```javascript Sentry.init({ @@ -355,7 +353,7 @@ To make sure you've enabled stream mode successfully: - + - **Check the Sentry dashboard**: Spans should appear in the Traces view shortly after they complete. Traces look the same as in transaction mode, but without transactions. - **Check for fallback warnings in your logs**: If the SDK logs warnings about falling back to transaction mode, your `beforeSendSpan` callback is likely missing the `Sentry.withStreamedSpan()` wrapper. diff --git a/platform-includes/performance/enable-stream-mode/javascript.effect.mdx b/platform-includes/performance/enable-stream-mode/javascript.effect.mdx new file mode 100644 index 0000000000000..92db7d88747b1 --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.effect.mdx @@ -0,0 +1,61 @@ + + + + +Opt in by adding `spanStreamingIntegration()` to your list of integrations when initializing the SDK in your client: + + + + +```javascript {filename: main.ts} +import * as Sentry from "@sentry/effect"; +import { Layer } from "effect"; +const SentryLive = Layer.mergeAll( + Sentry.effectLayer({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + integrations: [ + Sentry.browserTracingIntegration(), + // enables stream mode + Sentry.spanStreamingIntegration(), + ], + }), + Layer.setTracer(Sentry.SentryEffectTracer) +); +``` + + + + + + + +Then set the `traceLifecycle` option to `'stream'` when initializing the SDK in your server: + + + + +```javascript {filename: main.ts} +import * as Sentry from "@sentry/effect"; +import * as Layer from "effect/Layer"; +import { HttpLive } from "./Http.js"; + +const SentryLive = Layer.mergeAll( + Sentry.effectLayer({ + dsn: "https://0bf825b298517c83faeec706c2231e88@o4508324856070144.ingest.de.sentry.io/4510861650362448", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", + }), + Layer.setTracer(Sentry.SentryEffectTracer) +); + +const MainLive = HttpLive.pipe(Layer.provide(SentryLive)); +MainLive.pipe(Layer.launch, NodeRuntime.runMain); +``` + + + + + +To revert to transaction mode, remove `traceLifecycle` and `spanStreamingIntegration()` from these files. diff --git a/platform-includes/performance/enable-stream-mode/javascript.elysia.mdx b/platform-includes/performance/enable-stream-mode/javascript.elysia.mdx new file mode 100644 index 0000000000000..dd0e571319c4b --- /dev/null +++ b/platform-includes/performance/enable-stream-mode/javascript.elysia.mdx @@ -0,0 +1,25 @@ + + + + +Opt in by setting the `traceLifecycle` option to `'stream'` when initializing the SDK: + + + + +```javascript {filename: instrument.js} +import * as Sentry from "@sentry/elysia"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + // enables stream mode + traceLifecycle: "stream", +}); +``` + + + + + +To revert to transaction mode, set `traceLifecycle` to `'static'` (the default) or remove the option entirely. From bd5bdf01746a08b57221e85546468694798d1059 Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Fri, 22 May 2026 14:23:54 +0200 Subject: [PATCH 11/12] minor fixes --- docs/platforms/javascript/common/tracing/new-spans/index.mdx | 3 +-- .../performance/enable-stream-mode/javascript.effect.mdx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/platforms/javascript/common/tracing/new-spans/index.mdx b/docs/platforms/javascript/common/tracing/new-spans/index.mdx index 9b5c89e591553..90f88b832dc93 100644 --- a/docs/platforms/javascript/common/tracing/new-spans/index.mdx +++ b/docs/platforms/javascript/common/tracing/new-spans/index.mdx @@ -288,7 +288,6 @@ Sentry.init({ { name: /^GET \//, attributes: { - "http.response.status_code": 200, "http.route": "/api/status", }, }, @@ -337,7 +336,7 @@ Sentry.init({ If a matching span is a root span, all of its child spans are dropped as well. If a child span matches, only that span is dropped and its children are reparented to the nearest ancestor. -In stream mode, `ignoreSpans` is evaluated at span start, so only the span name and attributes available at that point are taken into account. Any name updates or additional attributes added while the span is active won't invluence whether the span is dropped. +In stream mode, `ignoreSpans` is evaluated at span start, so only the span name and attributes available at that point are taken into account. Any name updates or additional attributes added while the span is active won't influence whether the span is dropped. diff --git a/platform-includes/performance/enable-stream-mode/javascript.effect.mdx b/platform-includes/performance/enable-stream-mode/javascript.effect.mdx index 92db7d88747b1..248b852120e5d 100644 --- a/platform-includes/performance/enable-stream-mode/javascript.effect.mdx +++ b/platform-includes/performance/enable-stream-mode/javascript.effect.mdx @@ -42,7 +42,7 @@ import { HttpLive } from "./Http.js"; const SentryLive = Layer.mergeAll( Sentry.effectLayer({ - dsn: "https://0bf825b298517c83faeec706c2231e88@o4508324856070144.ingest.de.sentry.io/4510861650362448", + dsn: "___PUBLIC_DSN___", tracesSampleRate: 1.0, // enables stream mode traceLifecycle: "stream", From 95337d2183fe08d030d9a0a59bc928ae8695ada9 Mon Sep 17 00:00:00 2001 From: Sarah Mischinger Date: Fri, 22 May 2026 15:03:55 +0200 Subject: [PATCH 12/12] update span names in Drop Spans section --- docs/platforms/javascript/common/tracing/new-spans/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/platforms/javascript/common/tracing/new-spans/index.mdx b/docs/platforms/javascript/common/tracing/new-spans/index.mdx index 90f88b832dc93..a64bd533fd870 100644 --- a/docs/platforms/javascript/common/tracing/new-spans/index.mdx +++ b/docs/platforms/javascript/common/tracing/new-spans/index.mdx @@ -334,13 +334,13 @@ Sentry.init({ -If a matching span is a root span, all of its child spans are dropped as well. If a child span matches, only that span is dropped and its children are reparented to the nearest ancestor. +If a matching span is a service span, all of its child spans are dropped as well. If a child span matches, only that span is dropped and its children are reparented to the nearest ancestor. In stream mode, `ignoreSpans` is evaluated at span start, so only the span name and attributes available at that point are taken into account. Any name updates or additional attributes added while the span is active won't influence whether the span is dropped. -In transaction mode, `ignoreSpans` is evaluated at root span end rather than at span start. Review your existing rules to make sure the attributes you're matching on are passed when the span is created. +In transaction mode, `ignoreSpans` is evaluated at transaction end rather than at span start. Review your existing rules to make sure the attributes you're matching on are passed when the span is created. If you're auto-instrumenting and don't know what the initial name of a span is when it starts, enable SDK debug logging during development by setting `debug: true` when initializing the SDK.