How DeepSeek's limit actually works
According to DeepSeek's rate-limit documentation, the API limits concurrency: the number of requests your account has in flight for a given model at the same moment. A request counts from the time it is sent until its response has finished — for a streamed response, that means until the last chunk arrives. DeepSeek's pricing page currently lists 2,500 concurrent requests for deepseek-v4-flash and 500 for deepseek-v4-pro. There is no published requests-per-minute or tokens-per-minute tier table, so do not design around one.
Official facts at a glance
- The limit is concurrent in-flight requests per account, per model — not RPM or TPM buckets.
- Current published concurrency: deepseek-v4-flash 2,500; deepseek-v4-pro 500.
- Every API key on the same account shares that account's concurrency. Extra keys do not add capacity.
- When you exceed the limit, the API returns HTTP 429.
- You can ask DeepSeek to expand your capacity, and the docs state this is at no extra charge.
- While a request waits, DeepSeek keeps the connection alive: non-streaming responses receive empty lines, streaming responses receive SSE comments of the form ': keep-alive'.
- If inference has not started after 10 minutes, the server closes the connection.
What keep-alive does and does not promise
Keep-alive lines exist so idle-connection timeouts in proxies and clients do not kill a request that is queued. They are not a guarantee that the response will finish within any particular time, and they are not an SLA. Your HTTP client must tolerate them: a JSON parser should skip leading blank lines on non-streaming calls, and an SSE parser should ignore lines that start with a colon. Set your own finite deadline for the whole request so a stuck call cannot hold a worker forever.
Error code decision table
DeepSeek's error-code page lists what each status means. The table below groups them by what your client should do next.
| Code | Meaning | What to do | Auto-retry? |
|---|---|---|---|
| 400 | Invalid request format | Fix the request body | No |
| 401 | Wrong or missing API key | Check the key and Authorization header | No |
| 402 | Insufficient balance | Stop sending and top up the account | No |
| 422 | Invalid parameters | Correct the parameters named in the error | No |
| 429 | Sending too fast / concurrency ceiling reached | Pace or queue new requests | Yes, bounded backoff |
| 500 | Server-side issue | Wait briefly | Yes, bounded |
| 503 | Server overloaded | Wait briefly | Yes, bounded |
Meanings from DeepSeek's official error-code docs; the retry column is our suggested policy.
Suggested client retry policy
Everything in this section is our suggested policy, not an official DeepSeek requirement. Tune the numbers to your workload.
- Retry only 429, 500 and 503. Never automatically retry 400, 401, 402 or 422.
- Cap attempts at 3 in total (the first call plus two retries).
- Use exponential backoff with full jitter: sleep a random time between 0 and min(cap, base × 2^attempt), for example base 1 s and cap 20 s.
- If a Retry-After header is present, wait at least that long.
- Give each logical request a finite total time budget (for example 90 s for interactive traffic) across all attempts, and check it again after every failure before sleeping. A true hard deadline needs a cancellable worker or a client with a total timeout.
- Keep your own count of pending requests per model and queue new work before you reach the published ceiling.
What should I do with this DeepSeek error?
Pick the status code you received and whether a streamed response had already delivered text. Selections are processed locally by this tool; no key or logs are collected. Site ads/analytics follow the privacy policy. The steps are our authored guidance built on DeepSeek's official error-code and rate-limit pages, not official DeepSeek instructions.
Authored guidance, not official DeepSeek instructions
Automatic retry: allowed, bounded (limited attempts and time budget)
Do this, step by step
- Pace or queue new requests: your account has too many in flight for this model.
- Count in-flight requests per model across all keys and services on the account.
- Retry with bounded, jittered backoff only if nothing was delivered yet.
What not to do
- Don't add more API keys — they share the same account capacity.
- Don't retry immediately without backoff.
Evidence to capture privately
- Model name used
- Time of the failure with timezone (e.g. 2026-10-26 14:05 UTC)
- HTTP status code
- Request ID, if the response returned one
- The error message, sanitized: remove your API key and any prompt or user content
Queue pressure estimate
A rough check of how many requests you keep in flight. By Little's law, average in-flight requests ≈ arrival rate × average full request lifetime (including the whole streamed completion). DeepSeek's rate-limit page, checked October 26, 2026, lists 500 concurrent requests for deepseek-v4-pro and 2,500 each for deepseek-v4-flash and deepseek-v4-flash-vision-exp. If DeepSeek has approved more capacity for your account, your actual quota wins — enter it below. Expanded quotas can carry per-user_id sublimits; don't enter any private identifiers here. Worked cases: 10 req/s × 30 s ≈ 300 in flight, 60% of the deepseek-v4-pro baseline. 20 req/s × 30 s ≈ 600, which exceeds that baseline. Neither number predicts whether a given request will actually be rejected: averages hide spikes, and a 429 is not proof that this is the only cause.
Estimate only, not a guarantee
Defaults to the published baseline. If DeepSeek approved more capacity for your account, your actual quota wins.
≈ 300 requests in flight on average — 60% of 500. This average is under the limit you entered.
- Suggestions only: queue requests, reduce concurrency or token length, and measure p95 lifetime, not just the average.
- Averages hide spikes; this does not predict whether any request will be rejected.
- More API keys do not add account capacity.
Baselines from DeepSeek's rate-limit page, checked October 26, 2026.
Python retry skeleton (standard library only)
A minimal, readable starting point. It reads the key from the DEEPSEEK_API_KEY environment variable — never paste a real key into source code. It is non-streaming on purpose: streams need different handling, covered below. Its timeout is a per-operation socket timeout, not a guaranteed end-to-end deadline, and it reads Retry-After as whole seconds only.
import json, os, random, time, urllib.error, urllib.request
API_KEY = os.environ["DEEPSEEK_API_KEY"] # placeholder: set in your environment
URL = "https://api.deepseek.com/chat/completions"
RETRYABLE = {429, 500, 503}
MAX_ATTEMPTS = 3 # suggested policy, not an official limit
BASE, CAP = 1.0, 20.0 # backoff seconds
BUDGET = 90.0 # retry budget in seconds (see note below)
def chat(messages, model="deepseek-v4-flash"):
# Non-streaming only. Do not reuse this loop for stream=True.
body = json.dumps({"model": model, "messages": messages}).encode()
start = time.monotonic()
for attempt in range(MAX_ATTEMPTS):
remaining = BUDGET - (time.monotonic() - start)
if remaining <= 0:
raise TimeoutError("retry budget used up")
req = urllib.request.Request(URL, data=body, headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
})
try:
# timeout= is a per-operation socket timeout (connect, each
# read), NOT a hard end-to-end deadline: a server that keeps
# sending keep-alive blank lines can hold this call longer.
with urllib.request.urlopen(req, timeout=remaining) as resp:
return json.loads(resp.read()) # tolerates blank lines
except urllib.error.HTTPError as e:
if e.code not in RETRYABLE:
raise # 400/401/402/422: fix the cause, don't retry
wait = random.uniform(0, min(CAP, BASE * 2 ** attempt))
# Retry-After: numeric seconds only. An HTTP-date value is
# ignored here and the jittered backoff is used instead.
ra = (e.headers.get("Retry-After") or "").strip()
if ra.isdigit():
wait = max(wait, float(ra))
# Recompute the budget AFTER the failed attempt, before sleeping.
remaining = BUDGET - (time.monotonic() - start)
if attempt + 1 == MAX_ATTEMPTS or wait >= remaining:
raise
time.sleep(wait)
Limits of this sketch: BUDGET stops new attempts and skips sleeps that would overrun it, but it is not a hard wall-clock cancellation. The socket timeout applies to each connect or read, so a slow response can run past it. For a strict deadline, run the call in a worker you can cancel, or use an HTTP client with a total timeout. Retry-After is read as whole seconds only.
Retries cost money
A retry is a brand-new request. If the first attempt actually ran on the server before your client gave up — for example your own timeout fired, or the connection dropped while the answer was being generated — you may be billed for both generations. Keep attempts low, use a finite time budget, and log every retry with a request identifier you generate so you can reconcile spend later.
Never auto-replay a partially delivered stream
With stream=true, tokens reach your user as they are generated. If the connection breaks after some content has been delivered, an automatic retry produces a different answer and charges for a second generation, while the user has already seen half of the first. Treat a broken stream as a failure: show what arrived, mark it incomplete, and let the user or your application decide whether to start a fresh request. Only retry automatically when nothing has been delivered yet.
402 is not 429
402 means your balance is insufficient. Waiting will not fix it, and retrying in a loop just produces more 402s. Stop sending, alert whoever owns billing, and top up the account. A 429 is the opposite case: your balance is fine, you simply have too many requests in flight. Handle it by slowing down.
Worked concurrency example
Concurrency equals arrival rate multiplied by how long each request stays open. Suppose your app starts 10 new requests per second and each one takes about 30 seconds from send to final token. After the first 30 seconds you will have roughly 10 × 30 = 300 requests in flight at once. That is comfortably under 500 on deepseek-v4-pro. If responses slow down to 60 seconds each, the same traffic needs about 600 slots and would start returning 429 on deepseek-v4-pro. These numbers are illustrative arithmetic, not a benchmark. The practical lesson: latency changes your capacity, so count pending requests instead of guessing a universal requests-per-minute number.
Pacing and queueing
Put a small in-process counter or semaphore around every DeepSeek call, keyed by model. When the counter nears your target ceiling, hold new work in a queue rather than sending it and waiting for a 429. For background jobs, a durable queue lets you absorb spikes without blocking users. If you consistently run close to the limit, request a capacity expansion from DeepSeek rather than opening another account — splitting traffic across accounts to bypass the limit is not something we recommend.
Fallbacks: reduce impact, don't promise zero downtime
A secondary OpenAI-compatible provider or a degraded mode (cached answers, a smaller model, a polite error) can reduce the impact of a 503 spike. It does not guarantee that users never see an interruption: fallbacks have their own limits, different outputs, and separate costs. Test the switch-over path before you rely on it.
What to monitor
- Pending (in-flight) requests per model, against the published ceiling.
- Count of 429, 500 and 503 responses, and how many retries each logical request needed.
- End-to-end latency, because longer responses consume concurrency for longer.
- Any 402 response — page the billing owner immediately.
Sources and methodology
Checked on October 26, 2026 against DeepSeek's official documentation: the rate-limit page (https://api-docs.deepseek.com/quick_start/rate_limit), the error-code page (https://api-docs.deepseek.com/quick_start/error_codes) and the pricing page for current per-model concurrency (https://api-docs.deepseek.com/quick_start/pricing/). Statements labelled as suggested policy are our own engineering recommendations. deepseek.health is an independent site, not affiliated with DeepSeek; if the official docs change, they take precedence over this guide.
- DeepSeek rate limit docs — checked October 26, 2026
- DeepSeek error codes docs — checked October 26, 2026
- DeepSeek pricing & concurrency docs — checked October 26, 2026