[experiment] ref!: Remove transactions and the static trace lifecycle - #23240
Draft
Lms24 wants to merge 4 commits into
Draft
[experiment] ref!: Remove transactions and the static trace lifecycle#23240Lms24 wants to merge 4 commits into
Lms24 wants to merge 4 commits into
Conversation
Span streaming is now the only trace lifecycle. The SDK no longer sends transaction events, so every code path that only existed to build, scrub, filter or ship them is gone. Removed from core: the `traceLifecycle` option, `_convertSpanToTransaction`, the segment-span capture strategy and its deferred-capture queue, standalone spans, `beforeSendTransaction`, `ignoreTransactions`, `withStaticSpan` / `withStreamedSpan`, gen_ai span extraction, the v1<->v2 span converters, `hasSpanStreamingEnabled`, the `TransactionEvent` type and the `spans`, `measurements` and `transaction_info` fields on `Event`. Also removed the downstream hooks that no longer see any traffic: the transaction branches of `eventFilters`, `prepareEvent` span normalization, `scopeData` transaction naming, the vercel-ai transaction processor and its token-accumulation utils, and the legacy `preprocessEvent` paths in Next.js and SvelteKit (both already had `processSpan` counterparts). Legacy browser profiling goes too: it attached profiles to transaction envelope items and was therefore unreachable. UI Profiling (v2) is untouched. Web vitals simplify as well, since CLS/LCP/INP now always stream as their own spans. Three options had no streaming equivalent and are dropped rather than reimplemented, because `processSpan`/`processSegmentSpan` cannot drop a span: `httpIntegration`'s `dropSpansForIncomingRequestStatusCodes`, and the low-quality-transaction filters in Nuxt and SolidStart. Shipping this needs either a droppable streaming hook or `ignoreSpans`-based replacements. Tests are intentionally not updated; this branch measures bundle size impact. BREAKING CHANGE: The SDK no longer sends transaction events. `traceLifecycle`, `beforeSendTransaction`, `ignoreTransactions`, `withStaticSpan`, `withStreamedSpan`, `dropSpansForIncomingRequestStatusCodes` and legacy browser profiling (`profilesSampleRate`) are removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cf88354. Configure here.
Contributor
size-limit report 📦
|
Member
Author
|
well ... this is less than expected |
Second sweep over what the transaction removal left behind. All of this was reachable-but-dead: written by the SDK and read by nothing. `setMeasurement()` was the biggest find. It stores timed events on the root span, but the only reader was `timedEventsToMeasurements`, which fed the transaction event's `measurements` field. Under span streaming `getStreamedSpanJSON()` never looks at `_events`, so every call was a silent no-op that only accumulated memory. Removed the function, the conversion helper, `SentrySpan._events` and the `TimedEvent` type; `addEvent()` stays as a no-op because the OpenTelemetry Span interface requires the method. `@sentry/bundler-plugins` was the only internal caller and now sets plain span attributes instead. Also removed: `profile_id`, `exclusive_time`, `measurements` and `segment_id` from `SpanJSON` (all write-only — nothing reads them off a `spanToJSON()` result), the `transaction`/`transactions` fields on the v1 `Profile` type, `capturedSpanScope` / `capturedSpanIsolationScope` / `spanCountBeforeProcessing` from `SdkProcessingMetadata` plus the scope re-routing they drove in `captureEvent`, the orphaned `SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_*` and `SEMANTIC_ATTRIBUTE_PROFILE_ID` constants, the browser-only `profilesSampleRate` option left over from legacy profiling, and the `sentry.transaction` breadcrumb category (nothing emits it anymore). `spanToJSON`, `SpanJSON`, `getSpanDescendants` and `forceTransaction` are deliberately kept: they are read APIs used across 15 packages, back idle spans, and still mean "make this span a segment" respectively. BREAKING CHANGE: `setMeasurement()` is removed; use span attributes instead. `Span.addEvent()` no longer records anything. `profilesSampleRate` is removed from the browser SDK options. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Third sweep. `convertSpanLinksForEnvelope` existed only to fill `SpanJSON.links` and `TraceContext.links`, neither of which anything reads: `spanToTraceContext` emits just the three trace ids, and no caller touches `.links` on a `spanToJSON()` result. Streamed spans use `getStreamedSpanLinks` instead, so the whole v1 link path is gone along with both fields. Also removed `reparentChildSpans` (only the `beforeSendSpan`-over-transaction path called it) and five semantic attribute constants that were already `@deprecated` in favour of `@sentry/conventions/attributes` and had zero remaining references: `SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME`, `..._SEGMENT_ID`, `..._SDK_NAME`, `..._SDK_VERSION` and `SEMANTIC_ATTRIBUTE_URL_FULL`. `createSpanContainerItem` is no longer exported now that the gen_ai extraction path that used it is gone. On `SpanJSON` itself: it is deliberately kept. It is no longer transaction machinery but the SDK's span read API — 67 call sites across 44 files use `spanToJSON(span).op` and friends, and `spanToStreamedSpanJSON` is not a drop-in replacement (`name` vs `description`, serialized `attributes` vs raw `data`, lossy `'ok' | 'error'` status). Replacing it would be an API migration with real behaviour risk for roughly 2 KB of source, so only its genuinely dead fields were stripped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fourth sweep, over what removing legacy browser profiling left behind. Nothing constructs a v1 `profile` envelope item any more — profiling-node and the browser UI profiler both emit `profile_chunk` — so the whole v1 payload path is unreachable. Removed `convertJSSelfProfileToSampledFormat` and `enrichWithThreadInformation` from the browser profiler (their only caller was the deleted `createProfilePayload`), the `Profile` and `ThreadCpuProfile` / `ThreadCpuSample` types, the `ProfileItem` envelope item and its `'profile'` header, and `'profile'` from `EventType`. `ThreadCpuStack` / `ThreadCpuFrame` stay: the continuous (v2) profile type still uses them. This one is type-level plus ~3 KB of unreachable conversion code, so the bundle delta is essentially zero — it is API-surface cleanup rather than a size win, and is reported as such. Verified against the built output: the production browser bundle now contains zero occurrences of `transaction`, `measurement`, `TimedEvent` or the segment capture machinery. The single remaining `addEvent` is the deliberate OpenTelemetry-interface no-op. BREAKING CHANGE: The `Profile`, `ThreadCpuProfile`, `ThreadCpuSample` and `ProfileItem` types are removed, as is `'profile'` from `EventType`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Experiment — not for merge. Opened to get size-limit numbers for removing transactions in v12.
Span streaming becomes the only trace lifecycle: no transaction events, no
staticlifecycle, no standalone spans. Every code path that only existed to build, filter or ship transactions is deleted, including legacy browser profiling (it attached profiles to transaction envelope items) and the transaction branches of event processors in core, vercel-ai, Next.js and SvelteKit.A second commit removes what that left behind — code that was reachable but dead. The notable one:
setMeasurement()was a silent no-op, since the only reader of its timed events was the transactionmeasurementsfield. That's gone along withTimedEvent, the write-onlyprofile_id/exclusive_time/measurements/segment_idfields onSpanJSON, and thecapturedSpanScopescope-rerouting incaptureEvent.Three options had no streaming equivalent and are dropped rather than reimplemented, since
processSpan/processSegmentSpancannot drop a span:httpIntegration'sdropSpansForIncomingRequestStatusCodes, and the low-quality-transaction filters in Nuxt and SolidStart. Tests are intentionally not updated.