Skip to content

fix: stop gateway memory leak on cached agent and session expiry - #25332

Closed
NeroNarada wants to merge 6 commits into
NousResearch:mainfrom
NeroNarada:fix-25315-gateway-memory-leak
Closed

fix: stop gateway memory leak on cached agent and session expiry#25332
NeroNarada wants to merge 6 commits into
NousResearch:mainfrom
NeroNarada:fix-25315-gateway-memory-leak

Conversation

@NeroNarada

Copy link
Copy Markdown

Summary

Fixes a long-lived gateway memory leak introduced by cache/session lifecycle paths that never fully release state on agent eviction or expiry.

Changes

  • Ensure _evict_cached_agent() actually detaches and cleans the evicted agent on /new, /model, and related reset paths by invoking the existing soft-eviction cleanup path asynchronously.
  • Extend soft cleanup to clear _session_messages, releasing potentially large per-session histories.
  • Clear stale per-session dictionaries when idle session expiry finalizes a session:
    • _session_model_overrides
    • _session_reasoning_overrides
    • _pending_approvals
    • _update_prompt_pending
  • Add a bounded policy to quiet-mode tool-definition cache in model_tools.py:
    • cap at 8 entries
    • reset cache when over capacity before inserting a new key
  • Add regressions covering
    • evicted cached agent soft cleanup and message clearing,
    • session-expiry state-map cleanup,
    • tool-definition cache cap behavior.

Issue

@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/gateway Gateway runner, session dispatch, delivery comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management comp/tools Tool registry, model_tools, toolsets labels May 14, 2026

@liuhao1024 liuhao1024 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall: Solid multi-area fix — the session-scoped state cleanup, agent cache soft-release, and localhost proxy bypass are all well-targeted. One concern:

_tool_defs_cache clear-on-cap strategy risks perpetual thrashing

In model_tools.py:

if len(_tool_defs_cache) >= _TOOL_DEFS_CACHE_MAX_ENTRIES and cache_key not in _tool_defs_cache:
    _tool_defs_cache.clear()

When the gateway serves >8 distinct toolset configurations (which is plausible when different sessions have different enabled_toolsets/disabled_toolsets), the 9th distinct config clears the entire cache — not just the oldest entry. Every subsequent call with a config that was previously cached will miss, and the single freshly-inserted entry gets evicted on the next distinct config.

In the worst case (e.g. a gateway serving 10+ platform sessions each with unique toolset combos), this degrades to zero cache effectiveness: every call recomputes tool definitions, which is worse than having no cache at all.

Suggestion: Use an LRU-eviction approach (drop the oldest entry) or a random single-key eviction instead of clear():

if len(_tool_defs_cache) >= _TOOL_DEFS_CACHE_MAX_ENTRIES and cache_key not in _tool_defs_cache:
    # Evict the oldest entry instead of clearing everything
    oldest_key = next(iter(_tool_defs_cache))
    del _tool_defs_cache[oldest_key]

Or even simpler with collections.OrderedDict / dict (Python 3.7+ preserves insertion order):

if len(_tool_defs_cache) >= _TOOL_DEFS_CACHE_MAX_ENTRIES and cache_key not in _tool_defs_cache:
    _tool_defs_cache.pop(next(iter(_tool_defs_cache)), None)

This keeps the remaining 7 cached entries warm, which matters in a multi-session gateway.

@NeroNarada NeroNarada closed this May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery comp/tools Tool registry, model_tools, toolsets P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: gateway memory leak — _evict_cached_agent drops agents without cleanup, _session_messages never cleared

3 participants