Home → Help

Concurrency limit exceeded for user, please retry later

Too many requests from your account were in flight at the same time. The limit counts open requests, not requests per minute, and every key on the account shares it. Lower your parallelism, or let the requests already running finish — this 429 is safe to retry with backoff.

What you are seeing

Why it happens

The message comes from sub2api, the open-source gateway that many API relay services run on, so you can meet it on more than one provider. The limit is set per user account, not per key: two keys on the same account draw from the same pool. The sub2api default is 5 simultaneous requests.

The gateway does not reject the sixth request straight away. It parks it in a waiting line and starts it as soon as a slot frees up. We measured this on our own gateway on 14 October 2026 with a limit of 5: sending 10 requests at once, all 10 succeeded and the slowest took 8.3 seconds; sending 25 at once, all 25 succeeded and the slowest took 18.8 seconds. The extra requests waited instead of failing. So when you do see this error, your requests were not just over the limit for a moment — they stayed over it long enough that a request could not get a slot in time.

That is why it shows up with long requests rather than many short ones. A streaming answer, a reasoning model thinking for a minute, or an agent waiting on a tool call holds its slot the whole time. Five of those running at once fill the account, and everything behind them queues until it gives up.

Confirm it is this

Fire ten identical requests at once and look at the timings:

seq 1 10 | xargs -P 10 -I{} curl -s -o /dev/null \
  -w '%{http_code} %{time_total}s\n' \
  'YOUR_BASE_URL/chat/completions' \
  -H 'Authorization: Bearer YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"model":"YOUR_MODEL","messages":[{"role":"user","content":"Count from 1 to 150."}]}'

If the first few return quickly and the rest arrive in later waves, the waves are your limit at work. If some return 429 with this message, the waiting line overflowed — cut the number in -P until none do, and that is the parallelism your account really supports.

How to fix it

  1. Cap in-flight requests in your clientPut a semaphore around the API call, sized to your account limit: asyncio.Semaphore(5) in Python, p-limit in Node. A slower retry loop does not fix this; the limit counts open requests, so only fewer open requests do.
  2. Count every key on the accountIf a coding agent, a chat app and a script share one account, they share one limit. Give heavy batch jobs their own account, or schedule them for when the others are idle.
  3. Retry this one — with backoff and jitterUnlike a 429 for an empty balance, this one clears by itself as soon as running requests finish. Wait one to two seconds, add a random offset so your workers do not retry in lockstep, and try again.
  4. Lower the parallelism inside agentsAgent tools that spawn subtasks can open many requests at once. Most let you cap concurrent tasks or workers in their settings; set it at or below the account limit.
  5. Ask for a higher limit only for steady loadIf your workload genuinely needs more requests open at once all day, ask your provider. For bursts, queueing on your side is cheaper and faster than a bigger limit.
Requests sent at the same momentSucceededSlowest response
10 (limit 5)10 of 108.3 s
25 (limit 5)25 of 2518.8 s
On APICLAN every account can have 5 requests open at once, and extra requests wait in line instead of failing straight away. Our error log shows no customer request rejected for concurrency since 14 September 2026. If your batch work needs more parallel requests, write to support@apiclan.us with what you are running.

Related

Unexpected token '<' when calling an OpenAI-compatible API401 invalid API key — when the key looks right but still fails

Last checked 2026-10-14. Written from problems diagnosed on a live OpenAI-compatible gateway, not collected from other sites.