Trace clients released on run finalization
Memory leak in tracing module fixed — trace clients now release when runs abort or time out, not just on success. Heap growth cut in half.
When workflow runs were aborted, timed out, or encountered errors, the LangSmith trace clients and their entire object hierarchies stayed locked in memory. The cleanup code only ran on successful completion, so abandoned runs accumulated silently.
A new releaseTraceClient() function now unconditionally removes clients from the cache. It's called in finally blocks across three finalization paths — ensuring cleanup happens regardless of how a run ends.
Memory usage is now stable across repeated workflow executions. Heap growth dropped from 152 MB to 80 MB per cycle, and round-over-round growth collapsed from 75 MB to 6 MB. The remaining 80 MB is one-time lazy loading that plateaus after the first workflow build.
The fix lives in the tracing module used by the instance AI service, a background system that manages workflow execution context.
View Original GitHub Description
Summary
The module-level traceClients Map in langsmith-tracing.ts was only cleaned when a root run finished successfully via finishRun(). If a run was aborted, timed out, or the finishRun HTTP call failed, the Client and its entire RunTree hierarchy stayed in the Map indefinitely.
Add releaseTraceClient() that unconditionally deletes the entry, and call it from:
- finalizeMessageTraceRoot (normal message run completion)
- finalizeDetachedTraceRun (background task completion)
- deleteTraceContextsForThread (safety net on thread deletion)
Measured impact (parallel workflow building benchmark: 3 tabs × 3 rounds)
| Metric | Before | After |
|---|---|---|
| Heap leak (post-cleanup − baseline) | +152 MB | +80 MB |
| Round-over-round growth (R2→R3) | +75 MB | +6 MB |
| RunTree objects after cleanup | 127 | near 0 (expected) |
The remaining ~80 MB delta is one-time lazy loading (node type catalog, source maps, Zod schemas) that loads on first workflow build and stays flat across subsequent rounds.
Related Linear tickets, Github issues, and Community forum posts
<!-- Include links to **Linear ticket** or Github issue or Community forum post. Important in order to close *automatically* and provide context to reviewers. https://linear.app/n8n/issue/ --> <!-- Use "closes #<issue-number>", "fixes #<issue-number>", or "resolves #<issue-number>" to automatically close issues when the PR is merged. -->Review / Merge checklist
- PR title and summary are descriptive. (conventions) <!-- **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** -->
- Docs updated or follow-up ticket created.
- Tests included. <!-- A bug is not considered fixed, unless a test is added to prevent it from happening again. A feature is not complete without tests. -->
- PR Labeled with
Backport to Beta,Backport to Stable, orBackport to v1(if the PR is an urgent fix that needs to be backported) - I have seen this code, I have run this code, and I take responsibility for this code.