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
Jawaban singkat
429 berarti Anda mengirim request lebih cepat daripada batas request per menit paket Anda mengizinkan - ini tidak berhubungan dengan kredit atau kuota harian. Jika response menyertakan header Retry-After, tunggu tepat selama itu. Jika tidak, gunakan exponential backoff dengan jitter, dan secara terpisah batasi berapa banyak request yang sedang berjalan bersamaan.Rate limit vs. kuota
Ini dua batasan berbeda yang sering membingungkan:
- Kuota - total request yang diizinkan dalam jendela waktu lebih panjang (misalnya sehari). Kehabisan berarti menunggu reset, kadang berjam-jam lagi.
- Rate limit - request yang diizinkan per jendela waktu singkat (misalnya semenit). Mengenainya berarti memperlambat selama beberapa detik hingga semenit, bukan berjam-jam.
Di baliknya, kebanyakan API menerapkan rate limiting dengan salah satu dari token bucket (Anda mengumpulkan "token" request pada laju tetap dan menghabiskan satu per request, memungkinkan ledakan singkat) atau counter jendela tetap/bergulir (batas keras per menit kalender, direset pada batas waktunya). Mana yang digunakan sebuah API mengubah seberapa bergelombang traffic Anda bisa aman - token bucket lebih toleran terhadap lonjakan singkat dibanding jendela tetap.
Standar HTTP: RFC 6585 dan Retry-After
429 Too Many Requests bukan mitos khas satu penyedia saja - ini didefinisikan secara resmi dalam RFC 6585 (April 2012) sebagai kode status HTTP standar. Menurut RFC 9110, server yang mematuhi standar boleh menyertakan header Retry-After pada response 429 (atau 503), dalam salah satu dari dua bentuk:
- Bentuk delay-seconds - sebuah bilangan bulat, misalnya
Retry-After: 120, berarti tunggu 120 detik. - Bentuk HTTP-date - stempel waktu absolut, misalnya
Retry-After: Wed, 21 Oct 2026 07:28:00 GMT.
Jika ada, header ini bersifat otoritatif - server memberi tahu Anda persis kapan ia akan menerima request lagi. Jangan menumpuk exponential backoff Anda sendiri di atasnya; itu hanya menunda pemulihan Anda lebih lama lagi. Baru gunakan backoff jika header ini tidak ada.
Rate limit GetYouTubeTranscript
| Paket | Batas laju |
|---|---|
| Gratis | 60 req/menit |
| Bulanan ($5/bulan) | 200 req/menit |
| Tahunan ($4,50/bulan) | 300 req/menit |
Bagaimana ini sebenarnya diberlakukan
Retry-After yang dikirim, jadi perlakukan 429 mana pun dari API ini sebagai "tunggu hingga ~60 detik lalu coba lagi dengan backoff," menggunakan pola kode di bawah alih-alih mem-parsing header yang tidak akan ada.Menangani 429 dengan benar
Urutan langkah yang benar: periksa Retry-After terlebih dahulu, dan baru gunakan exponential backoff dengan jitter jika header itu tidak ada. Jitter (mengacak sedikit waktu tunggu) penting karena saat banyak klien mengenai batas secara bersamaan dan semuanya mencoba ulang dengan jadwal identik, mereka akan tersinkronisasi dan menciptakan "thundering herd" yang langsung memicu ulang batas yang sama.
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")Rate vs. konkurensi - masalah yang berbeda
Batas request per menit dan batas konkurensi yang sedang berjalan bukanlah hal yang sama. Menembakkan 50 request secara bersamaan dengan Promise.all bisa memicu 429 bahkan jika total Anda dalam satu menit masih jauh di bawah anggaran, karena server (atau proxy di depannya) mungkin juga membatasi koneksi simultan. Saat memproses banyak video secara batch, batasi konkurensi secara terpisah dari backoff rate-limit Anda:
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)))
);Untuk batch bervolume tinggi berkelanjutan, meningkatkan tingkat paket langsung menaikkan batas req/menit - lihat harga di dokumentasi API, atau mulai dengan 100 kredit gratis dari dashboard.
FAQ Rate Limit
Apa bedanya rate limit dan kuota?
Kuota membatasi total penggunaan dalam suatu periode (misalnya per hari). Rate limit membatasi berapa banyak request yang bisa Anda buat per satuan waktu (misalnya per menit), terlepas dari total penggunaan harian Anda - Anda bisa mengenai rate limit meski masih jauh di bawah kuota harian Anda. Lihat panduan kuota API YouTube kami untuk sisi kuotanya.
Apa arti response 429?
429 Too Many Requests didefinisikan secara resmi dalam RFC 6585 pada tahun 2012. Ini berarti Anda telah melampaui batas request-per-jendela untuk paket Anda - ini sinyal untuk memperlambat dan mencoba lagi, bukan berarti request Anda tidak valid atau kredit Anda habis.
Apa itu header Retry-After, dan haruskah saya selalu memercayainya?
Menurut RFC 9110, server boleh menyertakan header Retry-After pada response 429 atau 503, dalam salah satu dari dua bentuk: bilangan bulat detik (Retry-After: 120) atau HTTP-date absolut. Jika ada, patuhi persis alih-alih menumpuk backoff Anda sendiri di atasnya - server telah memberi Anda jawaban otoritatif tentang kapan harus mencoba lagi.
Berapa rate limit GetYouTubeTranscript, dan apakah ia mengirim header Retry-After?
60 request/menit pada paket gratis, 200 req/menit pada paket bulanan, dan 300 req/menit pada paket tahunan, diberlakukan sebagai jendela tetap 1 menit per API key (bukan jendela bergulir). Saat ini tidak ada header Retry-After yang dikirim pada 429, jadi terapkan backoff Anda sendiri (lihat kode di bawah) alih-alih mengharapkannya - karena jendelanya tetap, bukan bergulir, waktu tunggunya paling lama adalah sisa menit saat ini.
Apakah 429 mengurangi kredit?
Tidak - request yang kena rate limit tidak pernah dikenakan biaya. Hanya request yang berhasil yang menghabiskan kredit.
Haruskah saya membuka beberapa API key untuk mendapatkan throughput lebih besar?
Tidak - ini biasanya melanggar ketentuan penggunaan wajar penyedia, dan khusus di GetYouTubeTranscript, rate limiting sudah diberlakukan per API key, tetapi kredit dan status akun dilacak di level akun terlepas dari berapa banyak key yang Anda buat. Jika Anda butuh throughput lebih besar, tingkatkan paket Anda, yang secara langsung menaikkan batas req/menit.
Mengapa request saya gagal padahal saya masih di bawah batas request per menit?
Itu biasanya masalah konkurensi, bukan masalah rate - menembakkan 50 request secara paralel bisa membebani server bahkan jika total Anda dalam satu menit masih dalam anggaran. Gunakan pembatas konkurensi (seperti p-limit di Node atau semaphore di Python) untuk membatasi berapa banyak request yang berjalan bersamaan, terpisah dari berapa banyak yang Anda kirim per menit.
Terkait
- YouTube API Quota Exceeded: Causes and Fixes
- YouTube Transcript MCP Server: Setup Guide for Claude and Other AI Tools
- YouTube Transcripts in n8n: HTTP Request Workflow Guide
- GetYouTubeTranscript vs TranscriptAPI
- GetYouTubeTranscript vs youtubetotranscript.com
- GetYouTubeTranscript vs youtube-transcript.io