Blog

OpenAI API 429 "Rate limit reached for ... on tokens per min (TPM)": How to Fix It

Short answer

A 429 with "code": "rate_limit_exceeded" and the message Rate limit reached for <model> in organization org-... on tokens per min (TPM) means your organization or project used up its per-minute allowance for that model. It's temporary. The message tells you how long to wait (Please try again in 2.19s), and the Retry-After header does too when it's present.

  1. Wait and retry with backoff. Follow Retry-After, or back off exponentially with some random jitter.
  2. Send fewer tokens per minute. Lower max_tokens, trim the prompt, and limit how many requests run at once.
  3. If the message starts with Request too large for, one request is bigger than the whole per-minute limit. Waiting won't help; make the request smaller.

Rate limits apply per organization and project, not per key. A new key in the same project doesn't get a new allowance.

What the error looks like

From the OpenAI Python SDK, as raised in surp-hovhannes/bahk#434 (organization ID shortened):

text
RateLimitError: Error code: 429 - {'error': {'message': 'Rate limit reached for gpt-4.1-nano in organization org-... on tokens per min (TPM): Limit 200000, Used 182265, Requested 25038. Please try again in 2.19s. Visit https://platform.openai.com/account/rate-limits to learn more.', 'type': 'tokens', 'param': None, 'code': 'rate_limit_exceeded'}}

The same error can arrive mid-stream, as in warpdotdev/warp#13582:

text
{"type":"tokens","code":"rate_limit_exceeded","message":"Rate limit reached for gpt-5.4 in organization org-... on tokens per min (TPM): Limit 500000, Used 348280, Requested 231138. Please try again in 9.53s. ..."}

The requests-per-minute version, from Codex in openai/codex#10060:

text
Rate limit reached for organization org-<> on requests per min (RPM): Limit 3000, Used 3000, Requested 1. Please try again in 20ms.

And the version where one request is over the limit by itself (LIF-Initiative/lif-core#1162, openai/codex#38366):

text
openai.RateLimitError: Error code: 429 - Request too large for gpt-4.1-mini (for limit gpt-4.1-mini-long-context) on tokens per min (TPM): Limit 2000000, Requested 3200202
Request too large for gpt-5.6-luna in organization org-... on tokens per min (TPM): Limit 200000, Requested 208334. The input or output tokens must be reduced in order to run successfully.

How to read the numbers

Limit is your allowance per minute, Used is what you've already used in the current window, and Requested is what this request needs. The request is rejected when Used + Requested is over Limit. In the first example, 182,265 + 25,038 is over 200,000, so the request has to wait about two seconds.

Requested isn't only your prompt. OpenAI's rate limits guide says the limit is calculated as the maximum of max_tokens and the estimated tokens from the character count of your request. A high max_tokens reserves a lot of the minute's allowance even if the answer is short.

Which limit did you hit?

OpenAI measures RPM, RPD, TPM, TPD, IPM (images per minute) and, for some audio models, audio minutes. Any of them can run out first. Some other details from the guide:

  • Limits are set per organization and per project, and differ by model.
  • Long-context models have a separate limit for long-context requests, which is why the lif-core message says for limit gpt-4.1-mini-long-context.
  • Some model families share one limit. Calls to any model in a shared group count toward the same TPM.
  • Your limits rise with your usage tier (Free, Build, Launch, Grow), which goes up automatically with total credit purchases. You can see the current numbers under Settings > Organization > Limits.

Responses also carry headers that show where you stand:

Header Example Meaning
x-ratelimit-limit-tokens 150000 Tokens allowed in the window
x-ratelimit-remaining-tokens 149984 Tokens left
x-ratelimit-reset-tokens 6m0s Time until the token limit resets
x-ratelimit-remaining-requests 59 Requests left
Retry-After 56 Minimum seconds to wait, when present

Not every 429 is a rate limit

Several different problems return 429. The error codes page separates them by error.code:

error.code What it means Does waiting help?
rate_limit_exceeded Over a per-minute or per-day limit Yes
slow_down (type rate_limit_error) Your traffic grew too fast, even within your limits Yes, then ramp up more slowly
credit_balance_exhausted No prepaid credits left No, add credits
organization_spend_limit_exceeded, project_spend_limit_exceeded A spend limit you set was reached No, raise or remove the limit
organization_usage_limit_exceeded The organization's approved monthly usage limit was reached No, request a higher limit

OpenAI notes that retrying billing, spend or quota errors won't restore access. If your 429 isn't rate_limit_exceeded or slow_down, see OpenAI "credit_balance_exhausted" (429).

How to fix it

  1. Retry with backoff. If Retry-After is present, wait at least that long. Otherwise use exponential backoff with jitter, and cap the number of retries. Failed requests still count toward your per-minute limit, so retrying in a tight loop makes it worse.
  2. Mind the SDK's own retries. The official SDKs already retry eligible 429s according to their retry settings. If you also retry in your code, lower the SDK's max_retries or count its retries, so the two loops don't multiply.
  3. Lower max_tokens to what you expect the answer to need. It counts toward Requested.
  4. Cap concurrency. A queue that allows a fixed number of requests in flight keeps you under TPM more reliably than retries alone.
  5. Move non-urgent work to the Batch API. Batch jobs have their own queue limits and don't use your synchronous rate limits.
  6. Ramp up gradually. If you see slow_down, increase traffic in steps. The guide's rule of thumb: once you reach 1 million input tokens per minute, increase by no more than 50% every 15 minutes.
  7. Check who else uses the organization. Limits are shared by everyone in the organization or project. A teammate's batch job can use up your TPM.

A minimal pattern in Python:

python
import random, time
import openai
from openai import OpenAI

client = OpenAI(max_retries=0)  # handle retries here instead

def create_with_backoff(**kwargs):
    delay = 1.0
    for attempt in range(6):
        try:
            return client.responses.create(**kwargs)
        except openai.RateLimitError as e:
            if e.code != "rate_limit_exceeded":
                raise  # billing or spend limits: retrying won't help
            try:
                wait = float(e.response.headers.get("retry-after", ""))
            except ValueError:
                wait = delay
            time.sleep(wait + random.uniform(0, 0.5))
            delay = min(delay * 2, 30)
    raise RuntimeError("still rate limited after retries")

When the message says "Request too large"

Request too large for <model> ... on tokens per min (TPM): Limit 200000, Requested 208334 means this one request needs more than the whole per-minute allowance. It fails every time until you change it:

  • Shorten the input: send fewer documents, trim the conversation history, or summarize older turns.
  • Lower max_tokens.
  • Split the work across several smaller requests.
  • Use a model or tier with a higher TPM limit for that model.

In Codex, this shows as stream disconnected before completion: Request too large for .... Start a new thread or run /compact; see Codex "stream disconnected before completion".

Using a TeamoRouter key

TeamoRouter is an API gateway with one key for GPT, Claude, Gemini and DeepSeek. It's OpenAI-compatible (/v1/chat/completions and /v1/responses), so the OpenAI SDK only needs a different base URL and key. Requests made with a TeamoRouter key are billed per use to your TeamoRouter balance, not to your OpenAI organization, so they don't count against that organization's rate limits. A gateway can still return 429, so keep the backoff code above.

  1. Create an API key in the TeamoRouter console. It starts with sk-teamo-.
  2. Top up from $5. The top-up dialog takes cards. You can also click Pay with crypto and pay with USDT, USDC or ETH from any exchange app — the checkout shows which networks your amount supports (BEP20 works from $5). Step by step: Pay with USDT.
  3. Point the SDK at TeamoRouter:
python
from openai import OpenAI

client = OpenAI(
    api_key="sk-teamo-...",
    base_url="https://api.teamorouter.com/v1",
)

resp = client.responses.create(model="gpt-6-sol", input="Hello")
print(resp.output_text)

GET /v1/models lists the model IDs your key can use. Claude models use the Anthropic protocol (/v1/messages) with the same key; see the API integration guide.

FAQ

Will a new API key reset the limit? No. Limits apply to the organization and project. A new key in the same project shares the same allowance.

Why is Requested much bigger than my prompt? max_tokens counts too. The limit uses the larger of max_tokens and the estimated prompt size.

Is this the same as insufficient_quota? No. rate_limit_exceeded clears within seconds or minutes. Quota, credit and spend-limit errors stay until you add credits or change the limit.

How do I get higher limits on OpenAI? Limits rise with your usage tier, which depends on total credit purchases. Check your tier and current limits under Settings > Organization > Limits.

Next steps

Ready to connect?Log in · top up · create an API key — three steps to start.