Skip to content

Comments

feat(replay): Add traces_by_timestamp to replay event#18048

Open
billyvg wants to merge 8 commits intodevelopfrom
billy/replay-802-replay-sdk-needs-to-send-timestamps-w-trace-ids
Open

feat(replay): Add traces_by_timestamp to replay event#18048
billyvg wants to merge 8 commits intodevelopfrom
billy/replay-802-replay-sdk-needs-to-send-timestamps-w-trace-ids

Conversation

@billyvg
Copy link
Member

@billyvg billyvg commented Oct 28, 2025

In order to support moving our custom rrweb events to EAP, we need to send timestamps w/ trace ids so that we can identify which trace the event belongs to.

In order to avoid breaking changes, we should not change the current type of trace_ids field in the replay event, instead we add a new field traces_by_timestamp w/ type [transaction.start_timestamp, traceId][].

Previously, we would clear all trace ids after each replay segment. so if there is not a new transaction, segments would not have a trace id associated at all. I've changed this so that we always keep the most recent trace id in between segments.

Also previously, in order to associate a replay with a trace, we wait until after a type: transaction event is sent successfully. it's possible that the replay integration is loaded after this event is sent and never gets associated with any trace ids. in this case, I've changed it so that we take the trace id from current scope and propagation context, and I use -1 for the timestamp here, but could also change to use current ts.

Closes #19201 (added automatically)

@linear
Copy link

linear bot commented Oct 28, 2025

@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 25.56 kB - -
@sentry/browser - with treeshaking flags 24.08 kB - -
@sentry/browser (incl. Tracing) 42.36 kB - -
@sentry/browser (incl. Tracing, Profiling) 47.03 kB - -
@sentry/browser (incl. Tracing, Replay) 81.26 kB +0.11% +82 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 70.86 kB +0.1% +64 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 85.94 kB +0.1% +78 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 98.11 kB +0.08% +77 B 🔺
@sentry/browser (incl. Feedback) 42.29 kB - -
@sentry/browser (incl. sendFeedback) 30.23 kB - -
@sentry/browser (incl. FeedbackAsync) 35.22 kB - -
@sentry/browser (incl. Metrics) 26.74 kB - -
@sentry/browser (incl. Logs) 26.88 kB - -
@sentry/browser (incl. Metrics & Logs) 27.56 kB - -
@sentry/react 27.33 kB - -
@sentry/react (incl. Tracing) 44.72 kB - -
@sentry/vue 30.01 kB - -
@sentry/vue (incl. Tracing) 44.22 kB - -
@sentry/svelte 25.58 kB - -
CDN Bundle 28.11 kB - -
CDN Bundle (incl. Tracing) 43.2 kB - -
CDN Bundle (incl. Logs, Metrics) 28.95 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 44.03 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 68.1 kB +0.12% +76 B 🔺
CDN Bundle (incl. Tracing, Replay) 80.14 kB +0.09% +70 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81 kB +0.08% +60 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 85.57 kB +0.08% +67 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 86.46 kB +0.08% +61 B 🔺
CDN Bundle - uncompressed 82.22 kB - -
CDN Bundle (incl. Tracing) - uncompressed 127.93 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 85.05 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 130.76 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 209 kB +0.14% +288 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 245.1 kB +0.12% +288 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 247.92 kB +0.12% +288 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 257.9 kB +0.12% +288 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 260.71 kB +0.12% +288 B 🔺
@sentry/nextjs (client) 47.12 kB - -
@sentry/sveltekit (client) 42.81 kB - -
@sentry/node-core 52.15 kB +0.02% +10 B 🔺
@sentry/node 166.53 kB +0.01% +7 B 🔺
@sentry/node - without tracing 93.95 kB +0.02% +13 B 🔺
@sentry/aws-serverless 109.45 kB +0.01% +9 B 🔺

View base workflow run

@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 9,291 - 9,053 +3%
GET With Sentry 1,663 18% 1,684 -1%
GET With Sentry (error only) 6,150 66% 6,116 +1%
POST Baseline 1,186 - 1,210 -2%
POST With Sentry 588 50% 595 -1%
POST With Sentry (error only) 1,058 89% 1,069 -1%
MYSQL Baseline 3,215 - 3,320 -3%
MYSQL With Sentry 469 15% 453 +4%
MYSQL With Sentry (error only) 2,607 81% 2,676 -3%

View base workflow run

@billyvg
Copy link
Member Author

billyvg commented Oct 28, 2025

@sentry review

@billyvg
Copy link
Member Author

billyvg commented Oct 29, 2025

@sentry review

@billyvg billyvg marked this pull request as ready for review October 29, 2025 22:24
@billyvg billyvg requested a review from a team as a code owner October 29, 2025 22:24
@billyvg billyvg requested a review from chargome October 29, 2025 22:24
initialUrl: this._context.initialUrl,
errorIds: Array.from(this._context.errorIds),
traceIds: Array.from(this._context.traceIds),
traceIds: this._context.traceIds,
Copy link

Choose a reason for hiding this comment

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

Bug: Shared array reference corrupts replay context

In _popEventContext(), the traceIds array is assigned by reference without creating a copy. When _clearContext() is subsequently called, it only creates a new array via slice(-1) if the length is greater than 1. For arrays with length 0 or 1, both the returned context and this._context share the same array reference. This means subsequent modifications to this._context.traceIds will affect the already-returned event context, potentially corrupting replay event data. The fix should copy the array: traceIds: [...this._context.traceIds] or traceIds: this._context.traceIds.slice().

Fix in Cursor Fix in Web

if (this._context.traceIds.length === 0) {
const currentTraceId = getCurrentScope().getPropagationContext().traceId;
if (currentTraceId) {
this._context.traceIds.push([-1, currentTraceId]);
Copy link
Member

Choose a reason for hiding this comment

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

Could we put a comment in here explaining the -1 ?

@billyvg billyvg force-pushed the billy/replay-802-replay-sdk-needs-to-send-timestamps-w-trace-ids branch from 1985467 to 84b12da Compare February 5, 2026 21:38
@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

Codecov Results 📊


Generated by Codecov Action

In order to support moving our custom rrweb events to EAP, we need to send timestamps w/ trace ids so that we can identify which trace the event belongs to.

In order to avoid breaking changes, we should not change the current type of trace_ids field in the replay event, instead we add a new field traces_by_timestamp
@andreiborza andreiborza force-pushed the billy/replay-802-replay-sdk-needs-to-send-timestamps-w-trace-ids branch from 84b12da to f50a1cb Compare February 18, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(replay): Add traces_by_timestamp to replay event

3 participants