Skip to content

feat(experiment-tag): share RTBT session across subdomains with rolling timeout#336

Open
tyiuhc wants to merge 1 commit into
mainfrom
web/subdomain-sessionid
Open

feat(experiment-tag): share RTBT session across subdomains with rolling timeout#336
tyiuhc wants to merge 1 commit into
mainfrom
web/subdomain-sessionid

Conversation

@tyiuhc

@tyiuhc tyiuhc commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Reworks the behavioral-targeting (RTBT) SessionManager so that current_session conditions work across subdomains, mirroring Amplitude Analytics' session model.

Previously the RTBT session lived in sessionStorage, which is scoped per-tab and per-origin. That fragmented sessions across subdomains (and even tabs), so current_session targeting could never match events fired on a different subdomain.

Changes

  • Root-domain cookie storage — session id + lastEventTime are persisted in a cookie scoped to the registrable domain (resolved with a new synchronous getTopLevelDomainSync probe in util/cookie.ts), so the session is shared across subdomains and tabs.
  • Rolling inactivity timeout — the session rotates after 30 minutes of inactivity (same default as Analytics), configurable via the new WebExperimentConfig.rtbtSessionTimeout.
  • Activity = any Amplitude eventrecordActivity() is called at the top of BehavioralTargetingManager.trackEvent, upstream of the persistedEvents allowlist filter, so any observed event keeps the session alive (not just RTBT-relevant events). Reads use getCurrentSessionId() which does not extend the session.
  • Graceful fallback — when cookie I/O is blocked (private browsing, ITP), detected via a write-back check, the session degrades to an in-memory per-page session instead of throwing.
  • getOrCreateSessionId() is kept as a backwards-compatible alias.

Related PRs

Part of the cross-subdomain behavioral-targeting effort: #333 (RTBT relay protocol + RelayClient), #334 (dual-write events to relay), and #335 (wire relay iframe). The root-domain cookie reuses the same registrable-domain approach as #332 (cross-subdomain web_exp_id_v2 identity). This change is independent of the relay PRs (based on main) but pairs with them so a shared current_session matches across subdomains.

Test plan

  • SessionManager unit tests: cookie persistence, cross-instance sharing, rolling timeout (extend vs rotate), configurable timeout, start-time, clear, and in-memory fallback.
  • Updated event-storage / integration / evaluator suites to clear the session cookie between tests.
  • Full experiment-tag suite green (174 tests), eslint + prettier clean.
  • Manual cross-subdomain verification (set a current_session rule, fire events on a.example.com, confirm match on b.example.com).

Made with Cursor

…ng timeout

Rework the behavioral-targeting SessionManager to mirror Amplitude
Analytics' session model so RTBT current_session conditions work across
subdomains.

- Persist session id + lastEventTime in a root-domain cookie (resolved
  via a synchronous getTopLevelDomain probe) instead of per-tab
  sessionStorage, so the session is shared across subdomains and tabs.
- Rotate the session on a rolling inactivity timeout (default 30m,
  configurable via WebExperimentConfig.rtbtSessionTimeout).
- Treat any observed Amplitude event as session activity by calling
  recordActivity() at the top of trackEvent, upstream of the
  persistedEvents allowlist filter.
- Degrade gracefully to an in-memory per-page session when cookie I/O is
  blocked (private browsing, ITP), detected via cookie write-back.

Refs WEB-132.

Co-authored-by: Cursor <cursoragent@cursor.com>
@linear-code

linear-code Bot commented Jun 18, 2026

Copy link
Copy Markdown

WEB-132

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.

1 participant