가이드 목록으로
문제 해결·2026년 8월 5일·최종 업데이트 2026년 9월 30일·9분 분량

OpenAI API 속도 제한 — 어떤 제한에 걸렸는지, 읽는 방법, 해결하는 재시도

OpenAI의 429는 다섯 가지 상한 중 하나를 넘었다는 뜻이며, 어떤 상한인지에 따라 해결 방향이 서로 반대일 수 있습니다. 응답 헤더에서 답을 바로 읽는 방법과 오류를 실제로 멈추는 재시도 로직을 설명합니다.

마지막 검토일: .

OpenAI의 429는 다섯 가지 한도 중 하나를 초과했다는 뜻입니다 — 가장 먼저 해야 할 일은 어떤 한도인지 파악하는 것입니다. 한도에 따라 해결 방법이 정반대이기 때문입니다. 이 페이지에서는 각 한도가 측정하는 항목, 응답 헤더에서 답을 바로 읽는 방법, 실제로 오류를 멈추는 재시도 로직, 올바른 백오프로도 충분하지 않을 때의 대응 방법을 다룹니다.

검증 완료 2026년 9월 30일 — OpenAI의 속도 제한 문서 기준.

다섯 가지 한도 중 어느 것이든 오류를 발생시킬 수 있습니다

지표측정 항목일반적으로 문제가 되는 경우
RPM분당 요청 수작은 요청이 많은 경우 — 분류, 임베딩, 에이전트 루프
TPM분당 토큰 수큰 요청이 적은 경우 — 큰 검색 컨텍스트를 사용하는 RAG, 긴 문서
RPD일일 요청 수무료 및 하위 티어, 일일 할당량을 모두 소진하는 배치 작업
TPD일일 토큰 수동일하지만 토큰 단위로 측정
IPM분당 이미지 수이미지 생성 작업

가장 먼저 소진된 한도가 오류를 발생시키므로, “토큰 한도에는 한참 못 미친다”는 말만으로 속도 제한 가능성을 배제할 수 없습니다 — TPM에는 여유가 있어도 RPM에는 정확히 도달했을 수 있습니다. 한도는 키별이 아니라 조직 및 모델별로 적용됩니다. 키를 추가로 발급해도 할당량이 늘어나지는 않습니다.

429는 어떤 형태로 표시되나요?

응답(HTTP 429)
HTTP/1.1 429 Too Many Requests
retry-after: 12
x-ratelimit-limit-requests: 500
x-ratelimit-remaining-requests: 0
x-ratelimit-reset-requests: 12s
x-ratelimit-limit-tokens: 200000
x-ratelimit-remaining-tokens: 143820
x-ratelimit-reset-tokens: 17s

{
  "error": {
    "message": "Rate limit reached for gpt-5.4 in organization org-... on requests per min (RPM).",
    "type": "requests",
    "code": "rate_limit_exceeded"
  }
}

필요한 정보는 모두 해당 응답에 있습니다. 본문에는 차원(“requests per min (RPM)”)이 표시되고, 헤더에는 정확한 한도, 남은 양, 복구 시점이 표시됩니다.

헤더의미
retry-after재시도하기 전에 기다려야 하는 최소 초 수
x-ratelimit-limit-requests한도를 소진하기 전에 허용되는 최대 요청 수
x-ratelimit-remaining-requests소진하기 전에 남은 요청 수
x-ratelimit-limit-tokens허용되는 최대 토큰 수
x-ratelimit-remaining-tokens남은 토큰 수
x-ratelimit-reset-requests / -reset-tokens각 카운터가 재설정될 때까지의 시간 — 카운터는 독립적으로 재설정됩니다

사용량 티어

한도는 사용량 티어에 따라 정해지며, OpenAI는 누적 지출이 증가함에 따라 이를 자동으로 상향합니다:

등급자격 요건월간 사용량 한도
무료허용된 지역의 사용자월 $100
Tier 1결제액 $5월 $100
Tier 2결제액 $50월 $500
Tier 3결제액 $100월 $1,000
Tier 4결제액 $250월 $5,000
Tier 5결제액 $1,000월 $200,000

모델별 RPM 및 TPM 수치는 의도적으로 여기에 재현하지 않았습니다. 모델마다 다르고, 새 모델이 출시될 때 변경되며, 계정별로 조정될 수 있기 때문입니다. 따라서 서드파티 페이지에 게시된 수치 표는 특정 날짜를 기준으로 한 추측일 뿐입니다. 자신의 계정에 대한 두 가지 권위 있는 출처는 OpenAI 대시보드의 한도 페이지와 이미 수행한 모든 응답에 포함된 x-ratelimit-* 헤더입니다. 헤더를 확인하세요.

해결 방법: Retry-After를 준수한 다음 지터 적용

OpenAI의 공식 권장 방식은 지터가 포함된 지수 백오프이며, 응답에 Retry-After가 포함되어 있으면 이를 따르는 것입니다. 두 부분 모두 중요합니다. 헤더가 없으면 너무 일찍 재시도할 수 있고, 지터가 없으면 같은 순간에 실패한 모든 클라이언트가 같은 순간에 재시도하여 함께 실패합니다. 이런 동시 재시도 쇄도는 문제가 발생한 1초를 문제가 지속되는 1분으로 늘립니다.

backoff.py
import random, time
import openai

client = openai.OpenAI()

def call_with_backoff(fn, *, max_attempts=6, base=0.5, cap=30.0):
    """Retry 429s: honour Retry-After when present, jittered backoff otherwise."""
    for attempt in range(max_attempts):
        try:
            return fn()
        except openai.RateLimitError as err:
            if attempt == max_attempts - 1:
                raise
            # The server's own answer beats any formula you invent.
            retry_after = (err.response.headers or {}).get("retry-after")
            if retry_after:
                delay = float(retry_after)
            else:
                # Full jitter: sleep a random point in [0, 2^n * base], capped.
                # Without the randomness every client that failed at the same
                # instant retries at the same instant and fails again together.
                delay = random.uniform(0, min(cap, base * 2**attempt))
            time.sleep(delay)

resp = call_with_backoff(lambda: client.responses.create(
    model="gpt-5.4",
    input="Summarise this changelog in three bullets.",
))

TypeScript에서는 같은 형태로 작성합니다:

backoff.ts
import OpenAI from "openai";

const client = new OpenAI();
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

export async function callWithBackoff<T>(
  fn: () => Promise<T>,
  { maxAttempts = 6, baseMs = 500, capMs = 30_000 } = {},
): Promise<T> {
  for (let attempt = 0; ; attempt++) {
    try {
      return await fn();
    } catch (err) {
      const status = (err as { status?: number }).status;
      if (status !== 429 || attempt === maxAttempts - 1) throw err;

      const retryAfter = (err as { headers?: Headers }).headers?.get("retry-after");
      const delay = retryAfter
        ? Number(retryAfter) * 1000
        : Math.random() * Math.min(capMs, baseMs * 2 ** attempt);
      await sleep(delay);
    }
  }
}

const resp = await callWithBackoff(() =>
  client.responses.create({ model: "gpt-5.4", input: "Hello" }),
);

공식 SDK는 이미 429를 대신 재시도하므로, 대부분의 애플리케이션에서는 자체 HTTP 클라이언트로 호출을 감싸거나 다른 동작을 원할 때만 이것이 필요합니다. 예를 들어 백그라운드 작업에는 더 긴 한도를 적용하거나, 12초를 기다리는 것보다 오류를 즉시 반환하는 편이 나은 사용자 대면 요청에는 즉시 실패하도록 할 수 있습니다.

문제가 발생하기 전에 모니터링하세요

카운터는 실패한 응답뿐 아니라 모든 응답에 포함됩니다. 남은 값을 로깅하면 속도 제한이 장애가 아니라 게이지가 됩니다 — 출시로 인해 한도가 소진되기 며칠 전부터 여유 공간이 줄어드는 것을 확인할 수 있습니다.

observe_quota.py
# Log the remaining counters on every response, not just on failures.
# By the time you see a 429 the useful signal is already an hour old.
resp = client.responses.with_raw_response.create(model="gpt-5.4", input="…")
h = resp.headers

log.info(
    "openai_quota model=%s req_left=%s tok_left=%s reset_req=%s reset_tok=%s",
    "gpt-5.4",
    h.get("x-ratelimit-remaining-requests"),
    h.get("x-ratelimit-remaining-tokens"),
    h.get("x-ratelimit-reset-requests"),
    h.get("x-ratelimit-reset-tokens"),
)

parsed = resp.parse()   # the normal response object

이와 함께 갖춰 둘 만한 습관은 두 가지입니다. 429 개수가 아니라 x-ratelimit-remaining-tokens가 한도의 일정 비율 아래로 내려갈 때 알림을 설정하고, 재시도뿐 아니라 스케줄에도 지터를 추가하세요. 모든 작업을 :00에 실행하는 cron은 스스로 버스트를 만들어 냅니다.

백오프가 답이 아닌 경우

올바른 백오프는 버스트를 해결합니다. 한도를 초과하는 지속적인 수요에는 아무런 효과가 없습니다 — 그런 경우 재시도는 실패 시점만 늦출 뿐입니다. 대략적인 노력 순서에 따른 구조적 해결 방법은 다음과 같습니다:

  • 출력량을 제한하세요. 추론 토큰은 청구되고 출력으로 계산되므로, 제한 없는 생성은 TPM을 가장 빠르게 소진하는 방법입니다.
  • 검색된 컨텍스트를 줄이세요. TPM 한도에서는 검색된 청크를 절반으로 줄이면 비용 증가 없이 처리량이 두 배가 됩니다.
  • 모델 규모를 적절히 선택하세요. 분류 단계에 최상위 모델은 필요하지 않으며, 소형 모델에는 별도의 예산이 있습니다.
  • 작업을 분리하세요. 배치 작업과 지연 시간에 민감한 트래픽이 하나의 조직 수준 한도를 놓고 경쟁하는 것이 이 문제를 스스로 만든 가장 흔한 형태입니다.
  • 티어를 올리세요. 티어는 누적 지출에 따라 올라가므로, 이미 자동으로 진행 중인 경우가 많습니다.

모델 제품군 간 부하 분산

이 목록의 마지막 항목에서 게이트웨이의 가치가 드러납니다. Kunavo는 여러 모델 제품군에 걸쳐 OpenAI 호환 API를 제공합니다 — 동일한 SDK, 동일한 호출 형식, 하나의 키를 사용하므로 포화된 한도에서 작업을 옮길 때 두 번째 통합이 아니라 모델 문자열만 변경하면 됩니다:

gateway.py
from openai import OpenAI

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

# Same SDK, same call shape — the model string chooses the family.
client.chat.completions.create(
    model="gpt-5-6-terra",            # or claude-sonnet-5, claude-haiku-4-5, …
    messages=[{"role": "user", "content": "Hello"}],
)

구체적으로 말하면, 프로덕션 트래픽과 경쟁하던 배치 요약 작업을 claude-haiku-4-5에서 $0.70 / 1M당 $3.50로 실행할 수 있고, 지연 시간에 민감한 경로는 gpt-5-6-terra ($0.70 / $4.20) 또는 claude-sonnet-5 ($1.40 / $7.00)에 유지할 수 있습니다. 다른 제품군, 다른 대기열입니다.

이 방식이 하는 일과 하지 않는 일을 분명히 이해하세요. 하나의 계정과 하나의 모델에 의존하는 병목을 제거하고, 장애 발생 시 전환할 대상을 제공합니다. 용량을 만들어 내는 것은 아닙니다. 총량이 실제로 어떤 티어가 허용하는 수준을 초과한다면 답은 여전히 티어를 올리거나 작업량을 줄이는 것입니다. 모든 모델의 요금은 가격 페이지에 있으며, Anthropic 한도에 대한 동등한 대응 방법은 Claude API 429 rate_limit_error에 설명되어 있습니다.

자주 묻는 질문

OpenAI API 속도 제한은 어떻게 되나요?

OpenAI는 RPM(분당 요청 수), TPM(분당 토큰 수), RPD(일일 요청 수), TPD(일일 토큰 수), IPM(분당 이미지 수)의 5가지 차원을 동시에 측정하며, 어느 하나라도 초과되면 즉시 HTTP 429를 반환합니다. 실제 한도는 사용 등급과 특정 모델에 따라 달라집니다. 따라서 계정에 적용되는 권위 있는 수치는 OpenAI 대시보드의 조직별 limits 페이지와 모든 응답의 x-ratelimit-* 헤더에 있으며, 공개된 표에 있지 않습니다.

OpenAI 사용 등급은 어떻게 되나요?

2026년 9월 30일 현재 OpenAI는 6개 등급을 문서화하고 있습니다. 각 등급은 누적 결제액에 따라 잠금 해제되며 월별 사용 한도가 있습니다. Free(지원 지역에서 사용 가능, 월 $100), $5 결제 후 Tier 1(월 $100), $50 결제 후 Tier 2(월 $500), $100 결제 후 Tier 3(월 $1,000), $250 결제 후 Tier 4(월 $5,000), $1,000 결제 후 Tier 5(월 $200,000)입니다. 지출이 누적되면 자동으로 승급됩니다.

OpenAI의 429 rate_limit_exceeded 오류를 어떻게 해결하나요?

응답에 Retry-After 헤더가 있으면 이를 따르고, 없으면 지수 백오프와 무작위 지터를 적용해 재시도하세요. 이것이 OpenAI가 공식 문서에서 권장하는 방법입니다. 공식 SDK는 이미 자동으로 재시도하지만, 직접 작성한 HTTP 클라이언트는 이를 구현해야 합니다. 올바른 백오프 후에도 429가 계속되면 일시적인 폭주가 아니라 실제로 할당량을 초과한 것입니다. 해결책은 구조적이어야 합니다. 배치 크기를 줄이고, 최대 출력 토큰을 제한하며, 예약 작업을 1분 동안 분산하거나 더 높은 등급으로 이동하세요.

실제로 어떤 속도 제한에 걸렸는지 어떻게 알 수 있나요?

헤더를 확인하세요. x-ratelimit-remaining-requests가 0이면 요청 제한에 걸린 것이고, x-ratelimit-remaining-tokens가 0이면 토큰 제한에 걸린 것입니다. 두 제한은 독립적으로 재설정됩니다. x-ratelimit-reset-requests와 x-ratelimit-reset-tokens가 각각 복구되는 시점을 알려줍니다. 응답 본문에도 해당 차원이 표시됩니다. 둘 중 무엇인지 추측하면 시간이 낭비됩니다. 해결책이 서로 반대이기 때문입니다. 요청 제한에는 큐잉이 필요하고 토큰 제한에는 더 작은 프롬프트가 필요합니다.

속도 제한은 키별로 적용되나요, 조직별로 적용되나요?

키별이 아니라 조직별 및 모델별로 적용됩니다. API 키를 추가로 만들어도 할당량이 늘어나지 않습니다. 따라서 같은 조직의 바쁜 프로덕션 워크로드와 배치 작업은 동일한 한도를 두고 경쟁하며, 키를 추가하는 것보다 이들을 분리하는 것이 중요합니다.

게이트웨이가 OpenAI 속도 제한에 도움이 되나요?

한 계정의 모델별 한도가 병목인 경우에는 도움이 됩니다. 게이트웨이를 사용하면 동일한 키와 SDK 뒤에서 다른 모델 제품군으로 작업을 이동할 수 있기 때문입니다. 예를 들어 배치 요약 작업을 지연 시간에 민감한 트래픽과 동일한 큐에 둘 필요가 없습니다. 그러나 용량을 무한히 만들 수 있는 것은 아닙니다. 전체 사용량이 실제로 단일 등급이 허용하는 수준을 초과한다면 여전히 등급을 올리거나 작업량을 줄여야 합니다.

새 계정인데 왜 속도 제한을 받나요?

무료 및 Tier 1 계정에는 상위 티어에는 없는 일일 한도(RPD 및 TPD)가 있으므로, 규모가 작은 테스트 스크립트도 오후 한때 하루 허용량을 모두 소진할 수 있습니다. Tier 1은 누적 결제액이 $5에 도달하면 활성화됩니다.

429가 발생하면 비용이 드나요?

아니요 — 거부된 요청은 처리되지 않으며 청구되지도 않습니다. 발생하는 비용은 지연 시간과, 재시도 로직이 그 지연 시간을 처리하는 방식입니다.

API 키를 더 만들면 처리량이 늘어나나요?

아니요. 한도는 조직 및 모델별로 적용됩니다. 추가 키는 귀속 추적과 폐기에 유용할 뿐, 용량을 늘려 주지는 않습니다.

429를 직접 처리해야 하나요, 아니면 SDK에 맡겨야 하나요?

일반적인 경우에는 SDK가 처리하도록 두고, 기본 동작이 적합하지 않은 경우에만 직접 처리하세요. 예를 들어 즉시 실패해야 하는 사용자 대면 요청이나, 기본값보다 훨씬 긴 한도를 감당할 수 있는 백그라운드 작업이 이에 해당합니다.

실제로는 할당량 소진인 429는 어떻게 하나요?

월간 사용량 한도를 소진해도 429로 표시되며, 아무리 백오프해도 해결되지 않습니다 — 응답 본문이 두 경우를 구분해 줍니다. 헤더의 카운터가 정상인데도 계속 거부된다면 재시도 코드를 수정하기 전에 결제를 확인하세요.