YouTube Transcript API Rate Limit: What It Is and How to Handle 429s

Why APIs return 429 Too Many Requests, what RFC 6585 and the Retry-After header actually specify, how rate limits differ from daily quota, and how to implement correct retry and backoff logic.

00:08:00 · SEP 13, 2026

빠른 답변

429는 요금제의 분당 요청 상한보다 빠르게 요청을 보내고 있다는 뜻입니다 - 크레딧이나 일일 할당량과는 무관합니다. 응답에 Retry-After 헤더가 있다면 정확히 그 시간만큼 기다리세요. 없다면 지터를 더한 지수 백오프를 사용하고, 동시에 진행 중인 요청 수도 별도로 제한하세요.

속도 제한 vs. 할당량

이 둘은 자주 혼동되는 서로 다른 두 가지 제약입니다:

  • 할당량 - 더 긴 창(예: 하루) 동안 허용되는 총 요청 수. 소진되면 초기화될 때까지 기다려야 하며, 때로는 몇 시간이 걸릴 수 있습니다.
  • 속도 제한 - 짧은 창(예: 1분) 동안 허용되는 요청 수. 걸리면 몇 초에서 1분 정도만 속도를 늦추면 됩니다.

대부분의 API는 내부적으로 토큰 버킷(일정한 속도로 요청 "토큰"이 쌓이고 요청마다 하나씩 소모하며 짧은 버스트를 허용) 또는 고정/슬라이딩 윈도우 카운터(달력상의 1분마다 초기화되는 고정 상한) 방식으로 속도 제한을 구현합니다. 어느 방식을 사용하는지에 따라 트래픽이 얼마나 버스트할 수 있는지가 달라집니다 - 토큰 버킷은 고정 윈도우보다 짧은 스파이크를 더 잘 견딥니다.

HTTP 표준: RFC 6585와 Retry-After

429 Too Many Requests는 제공업체마다 임의로 만든 것이 아니라, 표준 HTTP 상태 코드로 RFC 6585(2012년 4월)에 정식으로 정의되었습니다. RFC 9110에 따르면, 규격을 준수하는 서버는 429(또는 503) 응답에 다음 두 형식 중 하나로 Retry-After 헤더를 붙일 있습니다:

  • 지연 초 형식 - 정수, 예: Retry-After: 120은 120초를 기다리라는 뜻입니다.
  • HTTP 날짜 형식 - 절대 타임스탬프, 예: Retry-After: Wed, 21 Oct 2026 07:28:00 GMT.

이 헤더가 존재한다면 이는 권위 있는 정보입니다 - 서버가 언제 다시 요청을 받아들일지 정확히 알려주는 것입니다. 그 위에 자체 지수 백오프를 겹쳐 적용하지 마세요. 그러면 복구가 오히려 더 늦어집니다. 헤더가 없을 때만 백오프로 대체하세요.

GetYouTubeTranscript의 속도 제한

요금제속도 제한
무료분당 60회
월간 (월 $5)분당 200회
연간 (월 $4.50)분당 300회

실제 적용 방식

이는 롤링 윈도우나 토큰 버킷이 아니라, API 키별로 고정된 1분 창입니다 - 카운터는 시계상의 분 경계에서 초기화됩니다. 현재 Retry-After 헤더를 보내지 않으므로, 이 API의 429는 존재하지 않는 헤더를 파싱하려 하지 말고 아래 코드 패턴처럼 "최대 약 60초 기다린 후 백오프로 재시도"로 다루세요.

429를 올바르게 처리하기

올바른 처리 순서는 다음과 같습니다: 먼저 Retry-After를 확인하고, 없을 때만 지터를 더한 지수 백오프로 대체하세요. 지터(대기 시간을 약간 무작위화하는 것)가 중요한 이유는, 많은 클라이언트가 동시에 제한에 걸려 모두 똑같은 일정으로 재시도하면 서로 동기화되어 같은 제한을 즉시 다시 유발하는 "thundering herd"가 발생하기 때문입니다.

Node.js:

async function getTranscriptWithRetry(videoId, apiKey, maxRetries = 4) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const res = await fetch(
      `https://getyoutubetranscript.com/api/v1/transcript?v=${videoId}`,
      { headers: { Authorization: `Bearer ${apiKey}` } }
    );
    if (res.status !== 429) return res.json();

    const retryAfter = res.headers.get('retry-after');
    const waitMs = retryAfter
      ? Number(retryAfter) * 1000
      : 500 * 2 ** attempt + Math.random() * 250; // exponential backoff + jitter
    await new Promise((r) => setTimeout(r, waitMs));
  }
  throw new Error('Rate limited after retries');
}

Python:

import os, time, random, requests

def get_transcript_with_retry(video_id, api_key, max_retries=4):
    url = "https://getyoutubetranscript.com/api/v1/transcript"
    for attempt in range(max_retries + 1):
        res = requests.get(url, params={"v": video_id}, headers={"Authorization": f"Bearer {api_key}"})
        if res.status_code != 429:
            return res.json()

        retry_after = res.headers.get("Retry-After")
        wait = float(retry_after) if retry_after else (0.5 * 2 ** attempt + random.uniform(0, 0.25))
        time.sleep(wait)
    raise RuntimeError("Rate limited after retries")

속도 vs. 동시성 - 별개의 문제

분당 요청 상한과 동시 진행 요청 상한은 같은 것이 아닙니다. Promise.all로 50개 요청을 동시에 보내면, 서버(또는 그 앞의 프록시)가 동시 연결 수도 제한할 수 있기 때문에, 분당 총량은 예산 내라 해도 429가 발생할 수 있습니다. 많은 동영상을 배치 처리할 때는 속도 제한 백오프와는 별도로 동시성을 제한하세요:

import pLimit from 'p-limit';

const limit = pLimit(5); // at most 5 requests in flight at once
const results = await Promise.all(
  videoIds.map((id) => limit(() => getTranscriptWithRetry(id, apiKey)))
);

지속적으로 높은 볼륨을 처리해야 한다면 요금제 등급을 올리는 것이 분당 요청 상한을 직접 높이는 방법입니다 - API 문서의 요금제를 확인하거나 대시보드에서 무료 크레딧 100개로 시작하세요.

속도 제한 FAQ

Q01

속도 제한과 할당량은 어떻게 다른가요?

할당량은 일정 기간(예: 하루) 동안의 총 사용량을 제한합니다. 속도 제한은 일일 총 사용량과 무관하게 단위 시간당(예: 분당) 가능한 요청 수를 제한합니다 - 일일 할당량은 여유가 있어도 속도 제한에 걸릴 수 있습니다. 할당량 쪽 내용은 저희 YouTube API 할당량 가이드를 참고하세요.

Q02

429 응답은 무엇을 의미하나요?

429 Too Many Requests는 2012년 RFC 6585에 정식으로 정의되었습니다. 요금제의 시간 창당 요청 상한을 초과했다는 뜻으로, 속도를 늦추고 재시도하라는 신호이지, 요청이 잘못되었거나 크레딧이 소진되었다는 뜻이 아닙니다.

Q03

Retry-After 헤더란 무엇이며 항상 신뢰해야 하나요?

RFC 9110에 따르면 서버는 429나 503 응답에 다음 두 형식 중 하나로 Retry-After 헤더를 포함할 수 있습니다: 초 단위 정수(Retry-After: 120) 또는 절대 HTTP 날짜. 있다면 자체 백오프를 겹쳐 적용하지 말고 정확히 그대로 따르세요 - 서버가 언제 재시도해야 하는지 권위 있는 답을 준 것입니다.

Q04

GetYouTubeTranscript의 속도 제한은 어떻게 되며, Retry-After 헤더를 보내나요?

무료 요금제는 분당 60회, 월간 요금제는 분당 200회, 연간 요금제는 분당 300회이며, API 키별로 고정된 1분 창(롤링 윈도우가 아님)으로 적용됩니다. 현재 429에 Retry-After 헤더를 보내지 않으므로 이를 기대하지 말고 아래 코드처럼 자체 백오프를 구현하세요 - 창이 롤링이 아니라 고정이므로 대기 시간은 현재 분의 남은 시간을 넘지 않습니다.

Q05

429가 발생하면 크레딧이 소모되나요?

아니요 - 속도 제한에 걸린 요청은 절대 과금되지 않습니다. 성공한 요청만 크레딧을 소모합니다.

Q06

처리량을 늘리려고 API 키를 여러 개 발급받아야 할까요?

아니요 - 이는 일반적으로 제공업체의 공정 사용 약관을 위반하며, GetYouTubeTranscript의 경우 속도 제한은 이미 API 키별로 적용되지만 크레딧과 계정 상태는 발급한 키 수와 관계없이 계정 단위로 추적됩니다. 더 많은 처리량이 필요하다면 분당 요청 상한을 직접 높여주는 요금제 등급 업그레이드를 이용하세요.

Q07

분당 요청 한도 내에 있는데도 요청이 실패하는 이유는 무엇인가요?

보통 속도 문제가 아니라 동시성 문제입니다 - 50개 요청을 병렬로 보내면 분당 총량이 예산 내라 해도 서버가 과부하될 수 있습니다. 분당 보내는 요청 수와는 별개로, 동시 진행 요청 수를 제한하는 동시성 리미터(Node의 p-limit이나 Python의 세마포어 등)를 사용하세요.

관련 콘텐츠