Limits and rate limits
Concurrency, requests-per-minute, key quota and 5h / 1d / 7d spend windows and plan limits on BigModel.io, the 429 errors each returns, and how to retry with backoff.
On this page
BigModel.io applies several independent limits. Each one returns HTTP 429 (402 for account spend caps, 403 for balance) with an error that names it, so read the code before you retry.
| Limit | Scope | Set by | Error | Retry-After |
|---|---|---|---|---|
| Concurrency | User | BigModel.io (per account) | 429 rate_limit_error "Concurrency limit exceeded for user" or "Too many pending requests" |
No |
| Requests per minute (RPM) | Group and user | BigModel.io (per group / account) | 429 rate_limit_exceeded |
Yes |
| Key quota | Key | You | 429 API_KEY_QUOTA_EXHAUSTED |
No |
| Spend windows 5h / 1d / 7d | Key | You | 429 rate_limit_exceeded "api key 5小时限额已用完" (or 日 / 7天) |
No |
| Plan limits daily / weekly / monthly | Plan | Plan definition | 429 USAGE_LIMIT_EXCEEDED |
No |
| Account spend caps weekly / monthly | Account | You | 402 spend_cap_reached |
Yes, until the reset |
| Free-model calls at a zero balance | User | BigModel.io | 429 rate_limit_exceeded |
Yes |
| Balance | Account | Your top-ups | 403 INSUFFICIENT_BALANCE |
No |
| Upstream provider limits | Model provider | Provider | 429 rate_limit_error |
Passed through if sent |
There is no per-key RPM or concurrency setting; RPM and concurrency apply to your account and the key's group.
#Concurrency
Each user has a maximum number of requests in flight at once, set per account. When all slots are busy, further requests wait briefly in a queue:
- If the queue is full, the request is rejected at once with 429 "Too many pending requests, please retry later".
- If a queued request waits too long for a slot, it fails with 429 "Concurrency limit exceeded for user, please retry later".
Streaming requests hold their slot until the stream ends, so long agent sessions use concurrency for longer. If you run many requests in parallel, cap your own client's parallelism and retry these 429s with backoff.
#Requests per minute
Groups and users can have an RPM limit, set by BigModel.io per group and per account. When it is exceeded, the response is 429 rate_limit_exceeded with a Retry-After header giving the seconds left in the current minute. Wait that long and retry.
While your balance is zero, calls to models priced at $0 have their own per-minute limit, reported the same way. Topping up removes it. See Trial credit & free models.
#Account spend caps
On Balance & billing you can set a weekly and a monthly USD cap on balance spend. Weeks start Monday 00:00 UTC and months on the 1st at 00:00 UTC. When a cap is reached, requests return 402 spend_cap_reached with Retry-After set to the seconds until the reset. Models priced at $0 stay available. Don't retry a 402 in a loop: wait for the reset or change the cap.
#Key quota and spend windows
You set these yourself per key in API Keys:
- Quota caps total USD spend on the key (0 = unlimited). When used up: 429
API_KEY_QUOTA_EXHAUSTED. You can raise it or reset the used amount. - Spend windows cap USD spend per 5 hours, 1 day and 7 days (0 = unlimited).
Windows are fixed, not rolling. A window starts when the key is first used, and resets once its duration has passed. The 429 carries no Retry-After; check reset_at instead:
curl https://bigmodel.io/v1/usage \
-H "Authorization: Bearer $BIGMODEL_API_KEY"{
"mode": "quota_limited",
"rate_limits": [
{ "window": "5h", "limit": 5, "used": 5, "remaining": 0, "window_start": "...", "reset_at": "..." }
]
}GET /v1/usage works even when the key is exhausted or expired. See Per-key limits & budgets.
#Plan limits
Keys in a plan group are limited by the plan's daily, weekly and monthly USD limits. When one is reached, requests return 429 USAGE_LIMIT_EXCEEDED until the period resets. GET /v1/usage shows the plan's usage and limits under subscription.
#Rate-limit headers
The gateway does not add its own x-ratelimit-* headers. If the model provider sends x-ratelimit-* or retry-after, they are passed through. The RPM limit above sets Retry-After itself.
#Retry with backoff
Retry 429 rate limits and 5xx errors; do not retry 400, 401, 402, 403 or quota / window / plan errors, which will fail the same way until something changes. Honour Retry-After when present, otherwise back off exponentially with jitter.
import os, random, time
import requests
URL = "https://bigmodel.io/v1/chat/completions"
HEADERS = {"Authorization": f"Bearer {os.environ['BIGMODEL_API_KEY']}"}
NO_RETRY = {"API_KEY_QUOTA_EXHAUSTED", "USAGE_LIMIT_EXCEEDED", "INSUFFICIENT_BALANCE"}
def chat(body, max_attempts=5):
for attempt in range(max_attempts):
r = requests.post(URL, headers=HEADERS, json=body, timeout=600)
if r.status_code < 400:
return r.json()
err = r.json() if r.headers.get("content-type", "").startswith("application/json") else {}
code = err.get("code") or (err.get("error") or {}).get("type")
message = (err.get("message") or (err.get("error") or {}).get("message") or "")
retryable = r.status_code >= 500 or (
r.status_code == 429 and code not in NO_RETRY and "限额" not in message
)
if not retryable or attempt == max_attempts - 1:
raise RuntimeError(f"{r.status_code} {code}: {message} (request {r.headers.get('X-Request-ID')})")
wait = float(r.headers.get("Retry-After") or min(30, 2 ** attempt))
time.sleep(wait + random.random())
print(chat({"model": "glm-5.3", "messages": [{"role": "user", "content": "Hello!"}]}))const URL = "https://bigmodel.io/v1/chat/completions";
const NO_RETRY = new Set(["API_KEY_QUOTA_EXHAUSTED", "USAGE_LIMIT_EXCEEDED", "INSUFFICIENT_BALANCE"]);
async function chat(body, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const r = await fetch(URL, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.BIGMODEL_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (r.ok) return r.json();
const err = await r.json().catch(() => ({}));
const code = err.code ?? err.error?.type;
const message = err.message ?? err.error?.message ?? "";
const retryable = r.status >= 500 || (r.status === 429 && !NO_RETRY.has(code) && !message.includes("限额"));
if (!retryable || attempt === maxAttempts - 1) {
throw new Error(`${r.status} ${code}: ${message} (request ${r.headers.get("x-request-id")})`);
}
const wait = Number(r.headers.get("retry-after")) || Math.min(30, 2 ** attempt);
await new Promise((res) => setTimeout(res, (wait + Math.random()) * 1000));
}
}
console.log(await chat({ model: "glm-5.3", messages: [{ role: "user", content: "Hello!" }] }));The OpenAI and Anthropic SDKs already retry 429 and 5xx with backoff (max_retries / maxRetries, default 2). Raise it for batch jobs rather than wrapping the SDK in another retry loop. To spread load, keep the number of parallel requests at or below your concurrency limit.
#Troubleshooting
429 "Too many pending requests". You are sending far more parallel requests than your concurrency. Limit parallelism in your client (a worker pool or semaphore).
429 "Concurrency limit exceeded for user". Requests queued too long. Reduce parallel requests, or shorten long streams. Contact Support if you need a higher limit.
429 rate_limit_exceeded with Retry-After. The RPM limit; wait the given seconds.
429 rate_limit_exceeded "api key 5小时限额已用完". A key spend window. Wait for reset_at, raise the window or reset its usage in API Keys.
429 rate_limit_error with no other detail. Usually the model provider's own limit. Retry with backoff, or try another model with the models fallback array.
#Related
Updated · View as Markdown