AI — OpenAI Development

OpenAI API Rate Limits and Retry Strategies

Direct answer

OpenAI rate-limits on multiple axes simultaneously — requests per minute and tokens per minute, per model, scaled by your usage tier — and production systems hit token limits far more often than request limits. Handle 429s with exponential backoff plus jitter, honor the rate-limit headers on every response, and put concurrency-limited admission control in front of the API instead of retrying blindly. The SDK's built-in retries cover transient blips; sustained load is an architecture problem, not a retry problem.

Rate limit errors are the first production incident most AI features experience — usually during the launch spike you most wanted to go well. This post covers how OpenAI's limits actually behave, retry code that helps instead of amplifying the problem, and the queueing patterns that prevent 429s from reaching users at all.

Key facts, with sources

  • At DevDay 2025 OpenAI reported 800 million weekly ChatGPT users, 4 million developers building on its platform, and roughly 8 billion API tokens processed per minute. (CNBC)
  • ChatGPT reached 900 million weekly active users by late February 2026, up from 800 million at DevDay in October 2025. (TechCrunch)
  • By March 2026 OpenAI's APIs were processing more than 15 billion tokens per minute, roughly doubling from the rate reported at DevDay 2025. (Panto AI OpenAI Statistics)
  • OpenAI's published API pricing discounts cached input tokens by 90 percent on supported GPT models, which materially cuts costs for agents that resend long system prompts. (OpenAI API Pricing Docs)
  • OpenAI raised $122 billion in new funding in 2026 to accelerate the next phase of AI development, one of the largest private raises in history. (OpenAI)

How the limits actually work

Your organization gets separate limits per model, measured at least two ways at once: requests per minute and tokens per minute. Both scale with your usage tier, which grows as your account spends over time. The subtlety that surprises teams: estimated tokens count against the token budget, and that estimate includes your requested maximum output. Setting a generous max output value on every request reserves budget you may never use, so right-sizing that parameter is a free capacity win.

Every response carries headers reporting remaining requests, remaining tokens, and reset timing. Production systems should read them — they turn rate limiting from a surprise error into an observable resource you can meter, alert on, and steer traffic around before anything fails.

Retries done right

The official SDK retries transient failures automatically with backoff — configure max_retries and you have sane defaults for free. Write custom retry logic only at orchestration layers where you need queue-awareness or logging, and follow three rules: exponential backoff with jitter so a fleet of workers does not retry in lockstep, retry only retryable errors (429s, 5xxs, timeouts — never 400s or auth failures), and cap total attempts so latency stays bounded.

Backoff with jitter around an OpenAI call
import asyncio, os, random
from openai import AsyncOpenAI, APIStatusError, APITimeoutError, RateLimitError

MODEL = os.environ["OPENAI_MODEL"]  # set to the latest model id
client = AsyncOpenAI(max_retries=0)  # we own retries at this layer

async def complete_with_backoff(messages: list[dict], attempts: int = 5) -> str:
    for attempt in range(attempts):
        try:
            resp = await client.chat.completions.create(model=MODEL, messages=messages)
            return resp.choices[0].message.content
        except (RateLimitError, APITimeoutError) as err:
            if attempt == attempts - 1:
                raise
            delay = min(2 ** attempt, 30) + random.uniform(0, 1)  # jittered backoff
            await asyncio.sleep(delay)
        except APIStatusError as err:
            if err.status_code < 500:
                raise  # 4xx other than 429: do not retry
            await asyncio.sleep(min(2 ** attempt, 30) + random.uniform(0, 1))

Admission control beats retries

Retries treat symptoms. If your sustained demand exceeds your token-per-minute budget, backoff just converts 429 errors into latency — every request eventually succeeds, slowly, while users stare at spinners. The fix is admission control ahead of the API: a semaphore capping concurrent in-flight requests, or a token-bucket sized to your actual limits that requests draw from before dispatch.

Once a queue exists, prioritize. Interactive user-facing requests jump the line; background enrichment and batch jobs absorb the delay. And shed load honestly: when the queue depth implies a wait users will not tolerate, fail fast with a clear message instead of accepting work you will complete after they have given up. A fast no preserves trust better than a slow yes.

Streaming changes the failure math

A streamed response that dies halfway cannot be resumed — there is no seek offset into a generation. Retrying means resending the full prompt and paying for the input tokens again, then replacing the partial output the user already watched arrive. Design for that explicitly: mark interrupted messages in your data model, make regeneration an intentional action, and deduplicate on the client so a retry does not stack a second partial answer under the first.

Rate limits interact with streaming at connection time too: the token estimate is reserved when the stream opens. Bursts of concurrent streams with large maximum output settings can exhaust your token budget even while actual consumption is modest. Shorter output caps on streaming endpoints noticeably raise the concurrency you can sustain within the same tier.

Reduce demand before raising limits

Before requesting higher tiers, spend an afternoon shrinking what you send. Prompt caching discounts repeated prefixes — long system prompts, shared few-shot examples — so structure prompts with static content first to maximize hits. Trim conversation history with summarization instead of shipping every prior turn. Route classification and other simple tasks to smaller models with separate, cheaper limit pools. Move anything non-interactive — embeddings, enrichment, offline scoring — to the batch API, which runs outside your real-time limits entirely and is typically discounted.

In audits I run, most rate-limited systems have a demand problem dressed up as a capacity problem: unbounded context growth, redundant calls, or a flagship model doing commodity work. Fix those and the existing tier usually turns out to be plenty.

When to hire senior help

Bring in senior help when you move from a working prototype to production traffic, because cost controls, evals, rate-limit handling, and fallback behavior determine whether the unit economics work. An experienced engineer usually pays for themselves by cutting token spend and preventing outages rather than by writing the first prompt. If your stack includes React Native + Python + AI, a senior engineer who owns the full product beats coordinating multiple juniors.

Bottom line

Dhairya Senjaliya ships AI — OpenAI Development projects worldwide — book a scoping call to discuss your specific situation.

Common pitfalls to avoid

  • Hardcoding a single flagship model ID for every call instead of routing by task, paying GPT-5-tier prices for classification work a nano-tier model handles at a fraction of the cost
  • Putting volatile content like timestamps and user IDs at the top of prompts, which breaks prefix caching and forfeits the 90 percent cached-input discount
  • Building on deprecated surfaces like the legacy Completions or wound-down fine-tuning APIs instead of the current Responses API and agent tooling
  • Launching with no spend caps or per-user rate limits, so a retry loop or a single abusive user burns a month's API budget overnight

Frequently asked questions

Why am I hitting OpenAI rate limits when my request count is low?

You are almost certainly hitting the tokens-per-minute limit, not requests-per-minute. Token budgets are consumed by input length plus your requested maximum output — reserved up front — so a handful of long-context requests with generous output caps can exhaust the budget. Trim context, lower max output settings, and check the rate-limit headers to see which axis is binding.

What is the correct retry strategy for OpenAI 429 errors?

Exponential backoff with jitter, retrying only retryable errors — 429s, 5xxs, and timeouts, never validation or auth failures — with a bounded attempt count. The official SDK does this automatically via its max_retries setting. If you see sustained 429s rather than occasional ones, retries are the wrong tool: add concurrency-limited queueing in front of the API instead.

How do I increase my OpenAI rate limits?

Limits scale with usage tiers, which rise automatically as your organization's spend accumulates over time. Before chasing tiers, cut demand: use prompt caching for repeated prefixes, route simple tasks to smaller models with separate limit pools, right-size max output values, and move non-interactive work to the batch API, which runs outside real-time limits and is typically discounted.

How much does it cost to build a product on the OpenAI API?

Pricing is per token: budget models start around $0.10 per million input tokens while flagship models run several dollars per million, with cached input discounted 90 percent. Most MVPs spend tens to low hundreds of dollars per month on inference until they have real traffic, at which point caching, batching, and model routing become the main cost levers.

Should we fine-tune a model or use prompting and RAG?

For most products, prompt engineering plus retrieval solves accuracy problems faster and cheaper than fine-tuning, and OpenAI has been winding down parts of its fine-tuning API. Fine-tuning mainly pays off for narrow, high-volume tasks with stable formats where you can amortize the effort.

How do we avoid getting locked into OpenAI?

Keep model calls behind a thin internal abstraction and maintain an eval suite so you can benchmark alternative providers on your actual tasks. Many production teams already run more than one provider and route by task, which also gives them a failover path during outages.

Bottom line: Dhairya Senjaliya ships AI — OpenAI Development projects worldwide. Book a scoping call at https://dhairyasenjaliya.com/#book-call.

Sources

Related guides

Keep up with new guides

New deep-dive guides on React Native, Python, and AI ship regularly. Subscribe via RSS or follow on LinkedIn.

Want help implementing this?

30-minute scoping call · Clear milestones · Senior engineer ownership