Skill 104 · Resolving Ingestion Warnings
Subchapter 104.12
references/fixing-merge-race-condition.mdMarkdown5 KBView on GitHub
Too many concurrent merge operations hit the same persons at once, and PostHog abandoned one of them to protect consistency.
Category merge, severity error: the event kept flowing, but that merge did not persist — the two persons stay separate until a later, uncontended identify/alias succeeds.
Unlike most warnings this one is never debounced — every occurrence lands, so the count is a true measure of how much merge contention the app generates.
A single user’s identity operations should be rare — once per login/signup. Contention on one person pair means something fires identify/alias for the same user in parallel:
identify() called on every request, page load, or render instead of once per session — a burst of parallel calls races itself.posthog:execute-sql: SELECT timestamp, details FROM system.ingestion_warnings WHERE type = 'merge_race_condition' AND timestamp > now() - INTERVAL 7 DAY ORDER BY timestamp DESC LIMIT 20. The details JSON carries both sides (sourcePersonDistinctId, targetPersonDistinctId, the person UUIDs) and the triggering event_uuid.posthog:persons-list, or posthog:execute-sql against the person-distinct-ID mapping). A person with hundreds or thousands of distinct IDs is a merge magnet — the race warnings are a symptom, and the real bug is whatever shared value keeps getting passed to identify (look at the person’s distinct ID list: an org slug, "user", an email domain, a device model repeating tells you exactly which value leaked in).posthog:execute-sql) for $identify/$create_alias events for the affected distinct IDs and look at their frequency and spacing — dozens of identifies per user per minute means an identify-per-request pattern; bursts at fixed times mean a batch job.Reduce the contention at its source:
identify must receive an ID unique to one human. The already-merged mega person is damage that code can’t cleanly undo; surface it to the user and recommend contacting PostHog support about splitting it rather than attempting programmatic repair.identify once when auth state changes (login/signup callback), not per request, per page, or per render. Guard with “already identified as this user?” checks where the SDK doesn’t already.No PostHog-side setting needs changing — the protection is doing its job; the app is supplying the race.
Re-run the flow, then re-query system.ingestion_warnings with posthog:execute-sql (filter type = 'merge_race_condition', timestamp after your fix) — counts should drop to the occasional benign collision (multiple devices logging in simultaneously) or zero. Confirm previously-affected users resolve to a single person, and that no person’s distinct ID count keeps climbing.