Repository navigation
[Feature]: requestPacing option to cap concurrent in-flight requests at provider and model level #5702
Description
Activity
github-actions commented
on Sep 23, 2026 on Sep 23, 2026 – with GitHub ActionsContributorMore actionsIssue reopened
The report now contains the information required by the automated check. Thanks for updating it.
- addedproxyHTTP proxy, routing, reverse-proxy / management authHTTP proxy, routing, reverse-proxy / management authstreamingSSE, WebSocket, terminal stream framesSSE, WebSocket, terminal stream frames
on Sep 23, 2026 Implementation PR: #5708 - adds requestPacing.maxConcurrentRequests at provider and model level, with the slot lease released when the upstream response body completes, errors, or is cancelled.
Scope note for #5708: the PR implements the provider-wide and per-model concurrency caps. Per-key caps (a limit counted per key inside a provider's key pool) are intentionally left out of this PR and stay open here, per the review in #5708 (comment). The PR counts every in-flight request against the provider regardless of which key it used; a per-key cap would need the lease keyed by credential, which is a separate slice on top of the lease machinery the PR adds.
- addedpriority: P2Medium: provider/client-specific bug with a workaround, bounded enhancement tied to a tracked issue,Medium: provider/client-specific bug with a workaround, bounded enhancement tied to a tracked issue,
on Sep 24, 2026 devin-ai-integration commented
on Sep 24, 2026 ContributorMore actionsTriage:
priority: P2— requestPacing concurrency cap (tracked, PR open).Criteria (P2): Medium: provider/client-specific bug with a workaround, bounded enhancement tied to a tracked issue, perf, or CI reliability.
Matched pull requests:
- feat(providers): requestPacing.maxConcurrentRequests at provider and model level #5708 (would resolve this issue) — feat(providers): requestPacing.maxConcurrentRequests at provider and model level [
priority: P2]
- feat(providers): requestPacing.maxConcurrentRequests at provider and model level #5708 (would resolve this issue) — feat(providers): requestPacing.maxConcurrentRequests at provider and model level [
Fixed on
devby #5954, carried in enhancement merge train batch 10B, #5992 (merge 35f267d).requestPacing.maxConcurrentRequestsis available at provider and model level. The lease is held across every physical send and released when the response body completes, errors or is cancelled; for Cursor the cap counts turns. Closing; please reopen if a build that includes 35f267d still exceeds the configured concurrency.
Area
Proxy and routing
What are you trying to accomplish?
Share one provider account (z.ai GLM coding plan) between long-running batch workloads and interactive Codex sessions through the proxy, and stay inside the upstream's concurrent-request limit so batch traffic stops eating 429s that also hurt interactive traffic.
What prevents this today?
requestPacing spaces outbound request starts: RPM becomes an even interval, minIntervalMs floors it, and dispatch waits its turn in waitForProviderRequestSlot. That works as documented, but z.ai enforces a concurrent in-flight request limit per account, not a request rate: HTTP 429, code 1302, "Rate limit reached for requests", whenever too many streaming turns are open at once. Start pacing cannot prevent that, because a long streaming turn consumes almost no request-rate budget while it holds a concurrency slot for minutes.
Evidence from a 2.54.0 proxy (single zai provider, one account, pacing enabled at 40 RPM / 1500 ms):
What should OpenCodex do?
Offer an optional concurrency cap in requestPacing, settable at both the provider and the model level like the interval controls today (default off):
Example usage or interface
Config fragment:
{ "providers": { "zai": { "requestPacing": { "enabled": true, "requestsPerMinute": 40, "minIntervalMs": 1500, "maxConcurrentRequests": 5, "models": { "glm-5.3": { "maxConcurrentRequests": 2 } } } } } } }Before/after: today a third concurrent glm-5.3 dispatch is sent upstream and returns 429/1302 after wasting a request slot; with the cap, that dispatch waits at the pacing boundary until one in-flight response body closes, then proceeds without touching the upstream limit.
Alternatives or workarounds
Keep client-side concurrency low (batch tools at concurrency 2-3) and avoid sharing one provider account between batch and interactive traffic. RPM pacing alone does not stop 1302-style errors. Both workarounds constrain the whole account for the sake of its slowest workload.
Additional context
Checked current main (4cb43cb): src/providers/request-pacing.ts tracks only next-start times; there is no in-flight accounting in the dispatch path. The release boundary (stream close vs response return, WS transport, key rotation) is the design-sensitive part, so I filed this before a PR per the contributing guide; happy to prototype once the intended boundary is confirmed.
Checks