Repository navigation
fix(browser): stop parsing persistence on every capture() for Meta identifiers - #5429
pauldambra wants to merge 3 commits into
Conversation
…changed capture() refreshed $fbc and $fbp from storage on every event, and every persistence write did the same. Each refresh parsed the whole persistence entry, and on localStorage+cookie it also wrote the entry back. With many feature flags this made click handlers slow (#5428). The refresh now compares the raw storage text with the text seen when the identifiers last matched storage, and parses only when it differs. Adds capture-hot-path tests that count parses of the persistence entry per capture, so CI fails if hot-path storage work comes back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 6ab57ee6-6279-4378-b074-ed4f92849780
Replay incident risk checkThis diff touches code involved in past incidents. This is a heads-up, not a verdict: read the matched sections of INCIDENTS.md and answer their review questions before merging. For a judgment on whether this diff has the same failure mode, run the |
There was a problem hiding this comment.
PostHog Review · Standard · reviewed 6290dc6: 1 Must fix, 1 Should fix.
This is the only automatic review while this pull request is a draft. Comment @posthog review to review new changes sooner. Otherwise, a review of the new changes runs when you mark it ready for review.
See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.
Coherence4 spec problems · 0 failing chokepoints · 2 spec gaps · 0 guard failures 44 components, 7 bullets (5 invariants, 2 requirements), 4 problems Spec problems (spec --check)
Chokepoints: none declared. Spec gaps: 2 entrances with outside or unknown trust and no traced control, and 10 more held by the adoption baseline
Close one with |
posthog-js Compliance ReportDate: 2026-10-25 17:33:31 UTC ✅ All Tests Passed!26/26 tests passed Capture Tests✅ 26/26 tests passed View Details
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 6ab57ee6-6279-4378-b074-ed4f92849780
|
Size Change: +9.54 kB (+0.04%) Total Size: 25.2 MB 📦 View Changed
ℹ️ View Unchanged
|
…er the pre-parse snapshot refreshMetaIdentifiers() read storage even when persistence was disabled. It now returns first. A refresh now remembers the storage text read before the parse, so a sibling write that lands during the parse is seen on the next refresh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 6ab57ee6-6279-4378-b074-ed4f92849780
|
Note 🤖 Automated comment by QA Swarm — not written by a human Multi-perspective review: router (cheap-first pass) + delegated lenses (qa-team, paul-reviewer, xp-reviewer, security-audit, engineering-systems-thinking as warranted) Verdict: ✅ APPROVE (round 1 @ dab9ae5)The router found no new problem beyond the two review threads, which are now fixed or answered. A second model checked the concurrency fix. Key findingsNone new. Two low notes were judged not actionable:
ConvergenceNone (only the router ran). Reviewer summaries
Automated by QA Swarm — not a human review |
Problem
Since 1.426.0,
capture()re-reads$fbcand$fbpfrom storage on every event. Every persistence write does it too. Each read runsJSON.parseon the whole persistence entry. OnlocalStorage+cookieit also writes the entry back tolocalStorage. With many feature flags the entry is big, so clicks get slower (INP), most of all on mobile.Why: the issue is right about the cause, and we want CI to catch this kind of hot-path regression in the future.
Closes #5428
Changes
persistence.refreshMetaIdentifiers(). It compares the raw storage text with the text it saw when the identifiers last matched storage. It parses only when the text is different, for example after another tab wrote. It parses the entry once for both keys.localStorage+cookiegets a_rawTextmethod that covers the cookie, the cookie metadata, andlocalStorage. This is so a sibling subdomain that writes only the cookie is still seen.capture-hot-path.test.ts. It counts how many times the persistence entry is parsed duringcapture(), over the persistence modes, with and withoutcookieWinsOnConflictand a stored$fbc. It counts work, not time, so a slow runner cannot make it flaky. Before this fix it found 4 parses percapture(). Now it finds 0. A second test checks that a sibling tab's$fbcis still adopted.Release info Sub-libraries affected
Libraries affected
Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Written with Claude Code in PostHog Desktop. I did not use the issue's first idea (skip the refresh when nothing is pending). People who came from a Meta ad have a stored
$fbc, so they would still pay for a parse on every click. I also did not use the second idea (move the refresh after the unchanged-write check). Almost every capture writes the session activity time, so that alone does not remove the parse. I compare raw storage text instead, likesyncCookiePropertiesalready does with_lastSeenMainCookieValue.Checked locally: the browser build (with the private-property check) and the full browser unit suite pass. No browser profile against posthog.com yet.
Created with PostHog Desktop
🤖 Generated with Claude Code