openai / openai/codex

MCP Streamable HTTP: sessions are opened but never terminated (1.8% DELETE ratio), exhausting remote server worker pools

Open
#41,600 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug connectivity mcp
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Version

codex-mcp-client/0.150.0-alpha.8

What happens

Codex opens MCP Streamable-HTTP SSE sessions against remote MCP servers and almost never tears them down. Concurrent sessions accumulate without bound, and because each open SSE stream pins a request worker on the server for the server's full stream timeout, the server's worker pool is exhausted by idle Codex sessions.

This is not a malformed-request or retry-on-error problem. Every request succeeds: 79,506 of 79,683 GETs returned HTTP 200, and the server opens a correct, spec-compliant stream each time.

Evidence

Measured from web-server access logs across three self-hosted WordPress MCP servers over 30 days (2026-07-31 → 2026-08-30), one Codex client, one source IP.

Session teardown ratio — the core defect:

method count meaning
GET 79,683 session / SSE stream opened
POST 10,996 JSON-RPC messages
DELETE 1,440 session terminated

1.81% of opened sessions are ever explicitly closed — roughly 55 opens per teardown.

Resulting concurrency. I verified the server holds a stream for a fixed 180s (measured directly: http=200 bytes=1175 total=181.44s), so average concurrent streams = opens x 180 / 86400:

date server A server B server C total concurrent
2026-08-02 6.9 8.6 4.9 20.5
2026-08-26 11.5 2.2 2.1 15.9
2026-08-27 54.0 13.2 13.0 80.3

On 2026-08-27 that meant ~80 worker processes pinned by idle Codex sessions on a 2-core host. Observed effects: 64 concurrent PHP workers on a single vhost, run queue 64, %user 89%, ~1.8 GB swapped with sustained swap-in, HTTP 503s, and the sites becoming unreachable. Load average dropped from 67 to 6 within ~8 minutes of disabling the MCP servers in Codex, with no other change.

No active use was required. There were no Codex sessions doing work against these servers during most of the accumulation — the sessions were configured, not driven.

Expected behaviour
  1. Terminate MCP sessions with DELETE when a session ends, rather than abandoning the stream.
  2. Reuse a single SSE stream per configured server instead of opening a new one alongside the existing ones.
  3. Cap concurrent sessions per server, and back off when opens outpace teardowns.
Impact

Any remote MCP server that implements Streamable HTTP with a long-lived SSE GET and a bounded worker pool — which is the common shape for PHP, Python WSGI, and Ruby servers — will have its worker pool exhausted by an idle Codex client. Self-hosted and shared-hosting deployments are hit hardest, since worker counts there are small.

Notes

The MCP server here is the AI Engine WordPress plugin. I verified its side is behaving correctly: it gates on Accept: text/event-stream (406 otherwise), opens a compliant stream, and closes cleanly at its configured timeout. Zero 406s were logged, so the client's requests are well-formed throughout.

This may be related to #31499 (duplicate stdio process pools on Windows), but that one concerns local stdio transports; this is remote Streamable HTTP session accumulation.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No source file or test is named. Start by locating the MCP Streamable HTTP session lifecycle and tracing how configured servers open, reuse, and close SSE streams; inspect the handling of session termination and concurrent opens. Done means sessions are explicitly terminated, streams are reused or bounded per server, and tests or measurements demonstrate that idle configured servers no longer accumulate sessions.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.