fix(core): Account for clock drift on every timestampInSeconds call - #23054
fix(core): Account for clock drift on every timestampInSeconds call#23054Lms24 wants to merge 1 commit into
timestampInSeconds call#23054Conversation
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 456dd81. Configure here.
| // See: https://dev.to/noamr/when-a-millisecond-is-not-a-millisecond-3h6 | ||
| if (Math.abs(timeOrigin + performanceNow - dateNow) > CLOCK_DRIFT_THRESHOLD_MS) { | ||
| timeOrigin = dateNow - performanceNow; | ||
| } |
There was a problem hiding this comment.
Rebased timestamps leave performance entries behind
Medium Severity
timestampInSeconds() updates only its private timeOrigin, while browserPerformanceTimeOrigin() retains its cached pre-drift origin. After sleep, spans use the corrected timeline but performance entries and profiles remain offset, causing post-wake telemetry to be dropped or assigned incorrect times.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 456dd81. Configure here.
size-limit report 📦
|
|
The two-origin divergence Bugbot flagged is real: Fixed in #23067, stacked on top of this PR, which exposes the corrected origin and switches over the consumers where the divergence persists (INP, replay, and profiling's Keeping it out of this PR so each change stays independently reviewable — this one is limited to how |
|
Confirmed on a real iPhone running React Native 0.86 with One structured log embedded its emission wall time in the message body:
The full structured-log stream was present under the older window with the same displacement, while error events remained wall-clock-correct. This matches the React Native Apple clock change in react-native#55977 and the symptom reported in getsentry/sentry-react-native#6510. We applied the same per-call re-anchoring shape downstream as a version-pinned patch. Package-level regression tests against the real One potentially useful addition to this PR's test suite: the current sleep test starts with an aligned first call and then accumulates drift. Our device also exercised the other entry condition, where |


This PR addresses clock drift observed in spans, logs, metrics and events caused by relying on
performance.now()after it became unreliable.My initial attempt to fix this in #22488 was flawed because it only checked for click drift on the first
timestampInSecondscall. Which is pretty useless given that clock drift likely occurs after the initial pageload (and hence SDK init). More specifically, when devices are put to sleep or browser tabs get suspended in the background.This fix therefore trades performance for more accurate time stamps by checking for clock drift on every
timestampInSecondscall. Once drift is detected, thetimeOriginis corrected withDate.now().Why not only use
Date.now()?performance.now()has sub-ms precisionperformance.now()is guaranteed to be monotonic.Date.now()can go backwards, or speed up/slow down its seconds (e.g. via NTP or user adjustments)Limitations:
supersedes #22488
supersedes #22585