Skip to content

feat(session-replay-browser): migrate sampling from Java hashCode to xxHash32#1629

Merged
lewgordon-amplitude merged 4 commits intomainfrom
xxhash-for-sr-sdk
Mar 26, 2026
Merged

feat(session-replay-browser): migrate sampling from Java hashCode to xxHash32#1629
lewgordon-amplitude merged 4 commits intomainfrom
xxhash-for-sr-sdk

Conversation

@lewgordon-amplitude
Copy link
Copy Markdown
Collaborator

@lewgordon-amplitude lewgordon-amplitude commented Mar 25, 2026

Summary

Replace the Java-style 32-bit hashCode with xxHash32 for session ID sampling to improve uniformity at high bucket resolutions (1M+) and ensure cross-platform determinism (Web/iOS/Android).

  • Add pure JS xxHash32 implementation based on the official spec
  • Update isSessionInSample to use xxHash32(sessionId) % 1_000_000
  • Add X-Sampling-Hash-Alg: xxhash32 header for server-side compat

Implements https://amplitude.atlassian.net/wiki/spaces/IG/pages/3375071237

SR-1841

Checklist

  • Does your PR title have the correct title format?
  • Does your PR have a breaking change?:

Note

Medium Risk
Changes the core session sampling decision algorithm, which can alter which sessions are recorded at a given sampleRate and impact event volume/coverage. Adds a new request header that backend systems may rely on for compatibility.

Overview
Updates Session Replay sampling to use a new deterministic xxHash32-based hash (hash % 1_000_000) via isSessionInSample, replacing the previous timestamp-based sampling helper.

Track requests now include X-Sampling-Hash-Alg: xxhash32 for server-side compatibility, and new unit/integration/e2e coverage is added to validate sampling decisions, determinism, and the emitted header (Playwright config now runs all *.spec.ts).

Written by Cursor Bugbot for commit e4e5136. This will update automatically on new commits. Configure here.

Replace the Java-style 32-bit hashCode with xxHash32 for session ID
sampling to improve uniformity at high bucket resolutions (1M+) and
ensure cross-platform determinism (Web/iOS/Android).

- Add pure JS xxHash32 implementation based on the official spec
- Update isSessionInSample to use xxHash32(sessionId) % 1_000_000
- Add X-Sampling-Hash-Alg: xxhash32 header for server-side compat

SR-1841

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lewgordon-amplitude
Copy link
Copy Markdown
Collaborator Author

bugbot run

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 25, 2026

Session Replay Browser E2E Results

passed  58 passed

Details

stats  58 tests across 3 suites
duration  58.4 seconds
commit  e4e5136

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@lewgordon-amplitude lewgordon-amplitude marked this pull request as ready for review March 25, 2026 13:42
@lewgordon-amplitude lewgordon-amplitude requested a review from a team as a code owner March 25, 2026 13:42
@lewgordon-amplitude
Copy link
Copy Markdown
Collaborator Author

@Mercy811 I wasn't sure if I should move this to core.

@Mercy811
Copy link
Copy Markdown
Contributor

@Mercy811 I wasn't sure if I should move this to core.

Thanks @lewgordon-amplitude, we can start with SR and move it to core later

lewgordon-amplitude and others added 2 commits March 25, 2026 13:01
Verify that the X-Sampling-Hash-Alg: xxhash32 header is sent on track
API requests, and that sampling in/out decisions are correct for known
session IDs with pre-computed xxHash32 ratios.

Also expand playwright testMatch from capture.spec.ts to *.spec.ts so
privacy.spec.ts (added in SR-2943) is included in the test run.

SR-1841

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two issues in the header test:
1. waitForRequest matched the CORS OPTIONS preflight (no X-Sampling-Hash-Alg)
   before the POST — fixed by predicating on POST method
2. blur alone may not guarantee a flush — added explicit sessionReplay.flush()
   matching the pattern used in flushRecording()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@jxiwang jxiwang left a comment

Choose a reason for hiding this comment

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

LGTM! Wonder why the lock diff is so big 🤔

@lewgordon-amplitude
Copy link
Copy Markdown
Collaborator Author

@jxiwang not sure. Let me check before merging.

The lockfile was reformatted by a different pnpm environment in this
worktree (multi-line → single-line resolution blocks, TypeScript peer
dep re-resolution). No package changes were made, so restore to main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lewgordon-amplitude
Copy link
Copy Markdown
Collaborator Author

@jxiwang not sure. Let me check before merging.

fixed!

@lewgordon-amplitude lewgordon-amplitude merged commit eb15e44 into main Mar 26, 2026
11 checks passed
@lewgordon-amplitude lewgordon-amplitude deleted the xxhash-for-sr-sdk branch March 26, 2026 12:36
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.

3 participants