Skip to content

fix(OPEN-11984): bound background-publish queue to stop unbounded memory growth - #661

Merged
gustavocidornelas merged 1 commit into
mainfrom
siddhant/open-11984-hi-team
Aug 3, 2026
Merged

fix(OPEN-11984): bound background-publish queue to stop unbounded memory growth#661
gustavocidornelas merged 1 commit into
mainfrom
siddhant/open-11984-hi-team

Conversation

@shah-siddd

Copy link
Copy Markdown
Contributor

Summary

  • A customer (Ashok) reported their FastAPI service OOMs after ~5 min / 20-30 requests when a function is decorated with @trace, but is stable without tracing (OPEN-11984).
  • Root cause: _handle_trace_completion submits every completed trace to a fixed 4-worker ThreadPoolExecutor for background publishing. That executor's internal work queue is unbounded, so if the Openlayer backend is slow/unreachable, queued Trace objects (each holding full step inputs/outputs) accumulate in memory without limit.
  • Fix: gate submission behind a threading.Semaphore sized by a new background_publish_max_queue_size config knob (default 100, configurable via init()). Once the cap is hit, new traces are dropped with a warning log instead of buffering indefinitely.
  • Secondary fix: _current_trace ContextVar was .set() at the start of every root trace but never .reset() (unlike _current_step), which could pin a stale Trace object in memory longer than necessary. Now captures a token and resets it via the existing _safe_reset_contextvar helper across all three code paths (plain functions, sync generators, async generators).

Test plan

  • ruff check clean
  • pytest tests/test_tracer_configuration.py tests/test_tracing_core.py — 57/57 passed, run 3x for flakiness
  • Manual smoke test confirming the semaphore blocks a 3rd concurrent submission when background_publish_max_queue_size=2, and releases correctly on completion
  • Manual smoke test confirming get_current_trace() returns None after a root trace completes (previously returned the stale trace)
  • Confirmed the handful of failures seen under -k trac (missing openai/litellm test deps, and generator-test cross-contamination under -n0) are pre-existing on main and unrelated to this change

Closes OPEN-11984.

🤖 Generated with Claude Code

…ded memory growth

A slow or unreachable Openlayer backend let traces pile up in the
ThreadPoolExecutor's unbounded work queue since each queued item holds
the full step inputs/outputs, causing traced FastAPI services to OOM
under sustained load. Cap the number of in-flight/queued traces via a
semaphore (background_publish_max_queue_size, default 100) and drop
with a warning once full instead of buffering indefinitely.

Also fix _current_trace ContextVar never being reset after a root
trace completes (only _current_step was reset), which could pin a
stale Trace object in memory longer than necessary.
@gustavocidornelas
gustavocidornelas merged commit b38265a into main Aug 3, 2026
5 checks passed
@gustavocidornelas
gustavocidornelas deleted the siddhant/open-11984-hi-team branch August 3, 2026 13:40
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.

2 participants