Repository navigation
feat(fallback): per-account RPM cap, default 40 for NVIDIA - #3203
Open
MuhammadUsamaMX wants to merge 3 commits into
Open
MuhammadUsamaMX wants to merge 3 commits into
MuhammadUsamaMX wants to merge 3 commits into
Conversation
This was referenced Aug 10, 2026
429 fallback currently locks an account for a fixed exponential backoff (getQuotaCooldown: base 2s … max 5m), ignoring the reset window the provider actually reports. So an account whose quota resets in 30m is retried every 5m (wasted 429s and fallback churn), while one that resets in seconds is held out far too long. Parse the provider's own reset signal from the 429 body/headers and use it as the cooldown instead: - Google/Antigravity RetryInfo "retryDelay": "1976.365s" (relative s) - OpenAI/Codex "resets_at" / "reset_at" (epoch s|ms) - OpenRouter / RateLimit headers "X-RateLimit-Reset" (epoch s|ms) - Retry-After: N (seconds) resolveCooldownMs() prefers the parsed reset, floors it at the static backoff (never retry sooner than before) and caps it at MAX_RATE_LIMIT_COOLDOWN_MS so a bogus/huge value can't wedge an account. Cap raised 30m -> 6h to accommodate real multi-hour resets (e.g. Codex). No signal present -> unchanged static backoff.
Add a per-provider retry-delay option so operators can set the cooldown applied when an account hits a rate-limit/error and the provider reports no reset window of its own. - Dashboard: a "Retry delay" selector on each provider page (Auto / 15s / 30s / 1m / 2m / 5m / 10m / 30m / 1h), saved to the new `retryDelayByProvider` setting via the existing /api/settings PATCH. - markAccountUnavailable honors it as a fallback only: a provider-reported reset (retryDelay / Retry-After / resets_at / X-RateLimit-Reset) is always used and never shortened. When the provider reports nothing, a configured value sets the lock duration; with "auto", free/free-tier provider pools cap the static backoff at 60s so a small account set recovers within its per-minute window instead of all locking for ~5m at once. Builds on the provider-reset-aware cooldown (uses parseProviderResetMs).
NVIDIA NIM enforces a per-API-key requests-per-minute limit. Crossing it
returns 429, which parks that account on a cooldown, so a burst can knock the
whole pool out for minutes at a time even though the accounts are healthy.
Count our own requests per account and skip an account that has used its
minute budget, so the provider never sees the 429 in the first place. When
every account for a provider is at its cap the request reports the wait like
any other rate-limit instead of failing hard.
The cap is per provider and editable from Providers -> [id] ("RPM / account",
next to Retry delay): blank uses DEFAULT_PROVIDER_RPM (40 for nvidia, unset
elsewhere) and 0 means unlimited, stored in settings.rpmByProvider.
Counters are in-process, which is the right scope for a single gateway; a
multi-instance deployment would need shared state.
MuhammadUsamaMX
force-pushed
the
feat/per-account-rpm-cap
branch
from
August 10, 2026 14:40
d9580ba to
5c91639
Compare
golamrabbi696
added a commit
to golamrabbi696/EzRouter
that referenced
this pull request
Aug 11, 2026
5 of 13 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
NVIDIA NIM enforces a per-API-key requests-per-minute limit. Crossing it returns 429, which parks that account on a cooldown — so a short burst can take the whole pool out for minutes even though every account is healthy. The limit is known up front, but nothing counts against it, so it is always discovered by tripping it.
Change
Count our own requests per account and skip an account that has already spent its minute budget, so the request goes to the next account instead of earning a 429.
src/sse/services/rpmLimiter.js— sliding 60s window per connection id:recordRequest,isOverLimit,retryAfterMs.getAuthfilters out capped accounts alongside model-locked/excluded ones, and records a request against whichever account it hands out.allRateLimitedshape with the time capacity comes back, rather than failing hard.RPM / account, beside Retry delay), stored insettings.rpmByProvider. Blank =DEFAULT_PROVIDER_RPM(40 fornvidia, unset elsewhere),0= unlimited.Counters are in-process. That is the right scope for a single gateway; a multi-instance deployment behind a load balancer would need shared state, and there is a
ponytail:note in the file saying so.Verification
Unit test in
tests/unit/rpmLimiter.test.jscovers unlimited-when-0, capping at the limit, the window sliding open again, per-account isolation, andretryAfterMs.End to end against a live instance with 7 NVIDIA accounts, cap temporarily set to 1:
Log line:
[AUTH] nvidia | all 7 accounts at the 1 RPM cap (30s). No 429 was sent upstream. After the window elapsed, requests succeeded again, and with the override removed the default of 40 applies.