fix(traces): evict aged spans only at the live-span bound - #5018
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
The PR appears safe to merge with no actionable correctness, security, or repository-rule violations identified. Reviews (1) · Last reviewed commit: "fix(traces): evict aged spans only at th..." |
posthog-node Compliance ReportDate: 2026-09-18 03:00:36 UTC ✅ All Tests Passed!46/46 tests passed Capture Tests✅ 29/29 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
posthog-js Compliance ReportDate: 2026-09-18 03:00:57 UTC ✅ All Tests Passed!26/26 tests passed Capture Tests✅ 26/26 tests passed View Details
|
|
Size Change: +110 B (0%) Total Size: 23.3 MB 📦 View Changed
ℹ️ View Unchanged
|
dustinbyrne
left a comment
There was a problem hiding this comment.
Looks good. Source-reviewed with AI assistance and existing CI evidence; no new tests executed.
Problem
Spans that run longer than
maxSpanAgeMs(1 hour by default) and then end normally are dropped. Once such a span passesmaxSpanAgeMs, the nextstartSpananywhere marks it as leaked, so when it ends, it is never exported, and its children, which were already exported, show up as orphans with no parent. Batch jobs, migrations and other long operations are exactly the spans people most want to see.Age eviction exists for leak recovery only: without it, leaked spans that fill
maxLiveSpanswould disable tracing for the rest of the process. Below that bound, an old live span costs nothing, because the SDK tracks just an id and a timestamp per span.Changes
@posthog/coreonly clears out old spans whenstartSpanfinds themaxLiveSpansbound reached. Below the bound, a long span that ends is exported with its full duration.startSpanafter they age out evicts them and records a real span.maxSpanAgeMsdoc comments in@posthog/typesand@posthog/corenow say it only applies oncemaxLiveSpansis reached.exports a long span that ends while under the boundis new, and it fails on the old code. Two existing tests now setmaxLiveSpans: 1so they still exercise the sweep, and they assert that a start is refused at the bound.This matches
posthog-python's traces stack (the change came from a review on PostHog/posthog-python#953) and the matching sdk-specs amendment toLive span bounds: PostHog/sdk-specs#68.Release info Sub-libraries affected
Libraries affected
@posthog/core(internal)Checklist
posthog-nodeusespackages/core/src/traces.maxSpanAgeMskeeps its name, type and default. The behavior changes: spans that were previously dropped are now exported, and leaks below the bound are no longer counted or warned about.If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Claude Code (Opus 5). Came out of documenting the posthog-python traces release, when the Python and Node docs disagreed about
maxSpanAgeMs. Python's behavior was kept as the better one, and Node and the spec were brought in line with it rather than the other way round.🤖 Generated with Claude Code