Skip to content

Conversation

@geekalaa
Copy link

@geekalaa geekalaa commented Aug 5, 2025

Fix memory leak in stateless StreamableHTTP sessions by creating request-scoped task groups instead of using the global task group, ensuring proper cleanup after each request.

Motivation and Context

Fixes #1221 - The simple-streamablehttp-stateless server had a memory leak where concurrent requests caused continuous memory growth without stabilization. Each stateless request was
spawning a long-lived task in the global task group without proper cleanup, causing task and resource accumulation over time.

How Has This Been Tested?

  • Created a reproduction script that makes 200 concurrent requests (20 batches × 10 concurrent calls each)
  • Before fix: Memory grew from 53.57 MB to 98.89 MB (+45.32 MB) with continuous growth
  • After fix: Memory grew from 53.98 MB to 101.84 MB but stabilized after batch 10 with no further growth
  • Existing unit tests pass for StreamableHTTPSessionManager
  • Tested with the simple-streamablehttp-stateless example server

Breaking Changes

None. This is an internal implementation change that maintains the same API and behavior.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

The fix creates a separate task group for each stateless request using async with anyio.create_task_group() instead of spawning tasks in the global session manager's task group. This
ensures that when the request completes, the task group is properly cleaned up along with any associated tasks and resources.

The memory stabilization observed in testing indicates that the leak has been resolved, with the remaining memory growth likely due to normal Python interpreter overhead and connection pooling.

geekalaa and others added 2 commits August 5, 2025 15:36
  Each stateless request was spawning a long-lived task in the global task group
  without proper cleanup, causing memory accumulation. This fix creates
  request-scoped task groups that are properly cleaned up after each request.

  Fixes:#1221
@geekalaa geekalaa requested review from a team and felixweinberger August 5, 2025 14:59
@geekalaa geekalaa closed this by deleting the head repository Aug 5, 2025
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.

simple-streamablehttp-stateless have member leak

1 participant