OpenAI API 429 Rate Limit Errors: RateLimitError and SDK Retries Explained
A 429 is two problems in one status: throughput limits vs quota exhaustion. The Python SDK already retries twice and honors Retry-After — this guide explains the mechanics from source.
When the OpenAI API returns 429, the official SDK raises RateLimitError. That status code covers two different problems — throughput rate limits (too many requests, wait and recover) and quota exhaustion (billing/allowance — waiting won't help). Telling them apart is step one, and the SDK already decodes the fields you need.
1. Read the error object, not just the message
RateLimitError extends APIStatusError. The fields that matter:
error.status_code: 429error.code/error.type/error.body: the SDK decodes the JSON error body into these — code/type separate rate limiting from quota problemserror.request_id: from thex-request-idresponse header — the only credential support can use to locate a single request
import openai
try:
resp = client.responses.create(model="gpt-5.6-terra", input="hi")
except openai.RateLimitError as e:
print(e.status_code, e.code, e.type, e.request_id)
2. The SDK already retries for you
Default behavior in openai-python (verified in _constants.py / _base_client.py):
| Mechanism | Default |
|---|---|
max_retries | 2 |
| Initial backoff | 0.5s, exponential |
| Per-retry cap | 8s |
| Auto-retried statuses | 408, 409, 429, ≥500 |
retry-after / retry-after-ms | honored (server-specified wait wins) |
x-should-retry | explicit server instruction overrides status rules |
Retry-After ceiling | SDK stops retrying beyond 120s |
So most transient 429s never reach your code — the SDK waits the server-specified time and retries behind the scenes. If you do see a 429, either the retry budget ran out or the server's requested wait exceeded the SDK's ceiling.
3. The debugging path
In order:
- Read
error.code/error.type— rate limit vs quota exhaustion are different roads - Capture
request_id— needed if you escalate to support - Rate limit: lower concurrency, space requests, add jittered backoff honoring
Retry-After, evaluate a higher tier or the Batch API - Quota exhausted: check the usage and billing dashboards — retries solve nothing
- Broad sustained 429s: check status.openai.com for a platform incident before blaming your code
4. Client-side best practice
If the default retry budget is not enough:
client = openai.OpenAI(max_retries=4) # raise the retry budget
Or roll your own backoff loop — the key rule is respect Retry-After: when the server tells you how long to wait, that beats any fixed exponential schedule. Add jitter to prevent thundering-herd retries.
5. Common mistakes
- Treating 429 as a bug: it is flow control, not a broken code path — the correct response is backoff and load reduction
- Retrying forever: a quota-exhaustion 429 never recovers on its own, and hammering amplifies pressure signals
- Ignoring x-request-id: without it, support cannot locate your request
6. Next steps
- OpenAI API Error Handling and Retry: 401/429/5xx Patterns — the full error taxonomy and retry patterns
- Responses API vs Chat Completions: Is It Time to Migrate? — which API surface to build on
Key points
- 429 maps to RateLimitError; error.code / error.type / error.body carry the root cause
- SDK default max_retries=2 with exponential backoff starting at 0.5s, capped at 8s
- Auto-retried statuses: 408, 409, 429, 5xx; the x-should-retry header wins over status rules
- retry-after / retry-after-ms are honored, but beyond 120s the SDK stops retrying
- Debug order: read error.code → capture x-request-id → check usage dashboard → lower concurrency or upgrade
Frequently asked questions
Official references
Related articles
openai-node v7.20.0 Explained: Environment-Variable Vault Credentials, External Storage, and Safety Cases
Six PRs in one openai-node release: environment_variable vault credentials, external storage management, safety case retrieval with two webhook events, a SIP media security field, and a legacy GET fix — each traced to PR and tag sources.
Read articleopenai-python 3.15/3.16 and openai-node 7.18/7.19: Cache Prewarming, Webhook Management, connector_id Deprecation
Six OpenAI SDK releases in one day: prewarm cache warming, client.webhooks endpoint management, connector_id deprecated for post-September-1 models, WebSocket sessions in both languages. Every item traced to its PR.
Read articleThe Responses API Compaction Progress Event: response.compaction.compacting and compaction_trigger
openai-node v7.17.0 adds a Responses API compaction progress event: response.compaction.compacting fires at most once every 30 seconds and carries no summary content. Set in context: trigger item, compact endpoint, context_management.
Read articleSubscribe to GPTMap Weekly
One email every Monday: curated OpenAI updates, deep dives, and best practices. No ads, unsubscribe anytime.
Submitting opens Buttondown in a new tab to confirm your subscription.