Skip to content

Add a global Gateway concurrency limit for upstream requests #21

Open

Description

@NOirBRight

Problem

The Python Gateway uses ThreadingHTTPServer, which creates a thread per connection and currently has no global upstream concurrency limit. During Codex App retry storms, repeated fast failures can amplify into local thread/resource pressure.

Scope

  • Add a simple global concurrency guard around upstream-generating requests.
  • Decide behavior when saturated: bounded wait, 429/503, or fast typed error.
  • Ensure health/status endpoints remain responsive where practical.

Acceptance Criteria

  • Upstream-generating requests are capped by a configurable limit.
  • Saturation is visible in telemetry with a distinct error code/classification.
  • Existing normal request behavior and tests remain stable.
  • Reconnect diagnostics can tell resource saturation apart from upstream transport failure.

Required Verification

python -m pytest tests/test_routing.py tests/test_proxy_event_logging.py

Related

Activity

  1. added
    needs-triageMaintainer needs to evaluate this issue
    enhancementNew feature or request
    ready-for-agentFully specified, ready for an AFK agent
    and removed
    needs-triageMaintainer needs to evaluate this issue
    on Jul 9, 2026
  2. NOirBRight commented on Jul 9, 2026

    @NOirBRight
    OwnerAuthor

    This was generated by AI during triage.

    Agent Brief

    Category: enhancement
    Summary: Add bounded Gateway upstream concurrency to prevent retry-storm resource amplification.

    Current behavior:
    System.Collections.Hashtable.Current

    Desired behavior:
    System.Collections.Hashtable.Desired

    Key interfaces:

    • Gateway request handler concurrency guard
    • Runtime settings/env configuration
    • Typed error/telemetry classification for saturation

    Acceptance criteria:

    • Upstream-generating requests honor a global limit.
    • Saturation produces a distinct status/error/telemetry signal.
    • Health/status endpoints remain responsive where practical.

    Out of scope:

    • Do not implement provider circuit breaker policy.
    • Do not tune limits without tests or documented defaults.
  3. wzg0911 commented on Jul 12, 2026

    @wzg0911

    Thread-per-connection with no upstream concurrency limit is a classic failure amplifier. We've seen this pattern in the wild — during Codex Hub-level retry storms, the lack of a global ceiling turns a transient transport failure into a resource cascade.

    Production observation: In one deployment, a single provider auth failure cascaded into rapid gateway restarts (every ~500ms) because each retry spawned a new thread, each thread hit the same dead auth path, and the OS thread scheduler compounded the latency. The fix was a global concurrency guard similar to what you're proposing.

    Design thoughts on the saturated-state behavior:

    • 429 is the cleanest option — it's a standard signal that clients already understand, and it preserves backpressure semantics.
    • Keep health/status endpoints on a separate, uncontended path (or at the OS level, before the gateway concurrency guard). Your AC already calls this out — worth making it explicit in the architecture.

    The #12/#16 telemetry work is a good prerequisite. Without measuring the actual concurrency pressure during storms, it's hard to tune the limit correctly your first try. Ship the telemetry first, read the data for a week, then set the initial cap.

  4. added
    needs-infoWaiting on reporter for more information
    and removed
    ready-for-agentFully specified, ready for an AFK agent
    on Jul 20, 2026
  5. NOirBRight commented on Jul 20, 2026

    @NOirBRight
    OwnerAuthor

    Moved to needs-info. Do not select a queue limit or saturation status until the #18 → #19 → #20 transport chain and #114 Direct Official / Gateway Luna / Gateway Volc fault injection produce measured concurrent-request, queue-pressure, retry, and first-failure evidence. A configuration or HTTP preflight is not sufficient proof for this policy decision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestneeds-infoWaiting on reporter for more informationwayfinder:taskWayfinder implementation task

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions