Tidak suka iklan? Pergi Bebas Iklan Hari ini

Pengaturan Batas Kecepatan Cara Menghentikan Diterima 429 oleh Setiap API yang Anda Gunakan

Diterbitkan pada

HTTP 429 Terlalu Banyak Permintaan — cara membaca header Retry-After, menerapkan penundaan eksponensial dengan jitter, memahami algoritma token bucket versus leaky bucket, dan menerapkan pembatasan laju pada API Anda.

Pengaturan Batas Kecepatan: Cara Menghentikan Diterima 429 oleh Setiap API yang Anda Gunakan 1
IKLAN · HAPUS?

Anda menemukan kode 429. Skrip Anda telah mengirim permintaan terus-menerus selama satu jam terakhir, log Anda penuh dengan warna merah, dan deployasi masih dalam waktu 20 menit. Itulah momen ketika hal ini berubah dari abstrak menjadi nyata.

Kode HTTP 429 Terlalu Banyak Permintaan berarti Anda mengirim lebih banyak permintaan daripada yang diizinkan oleh server dalam jangkauan waktu tertentu. Membaca respons dengan benar — dan mengulang permintaan dengan benar — adalah keterampilan yang sebagian besar pengembang hanya belajar setelah mengalami kegagalan. Berikut adalah gambaran lengkapnya.

Apa yang sebenarnya disampaikan oleh kode 429

Kode status hanya setengah dari pesan. Informasi sebenarnya terletak di header:

  • Retry-After: 30 — tunggu 30 detik sebelum mengulang. Bisa juga berupa tanggal HTTP: Retry-After: Mon, 08 Jun 2026 15:00:00 GMT
  • X-RateLimit-Limit: 100 — jumlah total permintaan yang diizinkan dalam jangkauan waktu
  • X-RateLimit-Remaining: 0 — jumlah permintaan yang tersisa dalam jangkauan waktu saat ini (Anda berada di nol)
  • X-RateLimit-Reset: 1749391200 — waktu timestamp Unix saat jangkauan waktu direset

Tidak semua API mengirimkan semua informasi ini. GitHub mengirimkan seluruh set. Stripe mengirimkan Retry-After. Beberapa API REST tidak mengirimkan apa-apa dan mengharapkan Anda menebak. Jika Anda memiliki Retry-After, gunakan nilainya secara tepat — itu adalah waktu minimum yang diizinkan oleh server. Jika Anda tidak melakukannya, maka pengulangan eksponensial adalah jalan keluar Anda.

Cara yang salah untuk mengulang permintaan

Implementasi yang sederhana tampak seperti ini:

async function fetchWithoutBackoff(url) {
  while (true) {
    const res = await fetch(url);
    if (res.ok) return res;
    if (res.status === 429) continue; // immediately retry
  }
}

Ini secara aktif merugikan. Jika 10 instance layanan Anda semua menemukan kode 429 pada saat yang sama dan segera mengulang, maka setiap pengulangan akan datang pada waktu yang sama — masalah kelompok yang terdengar seperti hujan. Anda kembali terbatas laju, segera, dalam loop yang ketat yang bisa berlangsung tanpa henti dan membuat klien Anda terlihat seperti secara sengaja memanfaatkan API.

Pengulangan eksponensial dengan gangguan acak

Polanya yang benar: setiap pengulangan menunggu lebih lama dari pengulangan sebelumnya (eksponensial), dan offset acak mencegah pengulangan yang terkoordinasi di antara beberapa klien (gangguan acak).

async function fetchWithBackoff(url, options = {}, maxRetries = 5) {
  let attempt = 0;

  while (attempt <= maxRetries) {
    const res = await fetch(url, options);

    if (res.ok) return res;

    if (res.status !== 429) {
      throw new Error(`Request failed: ${res.status}`);
    }

    if (attempt === maxRetries) {
      throw new Error(`Rate limited after ${maxRetries} retries`);
    }

    // Use Retry-After if provided; otherwise exponential backoff + jitter
    const retryAfter = res.headers.get('Retry-After');
    let waitMs;

    if (retryAfter) {
      const seconds = isNaN(retryAfter)
        ? (new Date(retryAfter) - Date.now()) / 1000  // HTTP date
        : Number(retryAfter);                          // seconds
      waitMs = seconds * 1000;
    } else {
      const baseDelay = 1000 * Math.pow(2, attempt); // 1s, 2s, 4s, 8s, 16s
      const jitter = Math.random() * 1000;            // 0–1000ms random offset
      waitMs = baseDelay + jitter;
    }

    console.log(`Rate limited. Waiting ${Math.round(waitMs / 1000)}s (attempt ${attempt + 1}/${maxRetries})`);
    await new Promise(resolve => setTimeout(resolve, waitMs));
    attempt++;
  }
}

Bagian gangguan acak adalah bagian yang paling sering dilewatkan oleh implementasi. Tanpa gangguan acak, pengulangan dari beberapa proses paralel masih datang dalam kelompok. Dengan gangguan acak, mereka tersebar di seluruh jangkauan waktu tunggu.

Untuk API yang mengembalikan Retry-After, gunakan nilai tersebut sebagai floor — jika Anda masih menerima kode 429 setelah waktu tunggu yang ditentukan, terapkan pengulangan eksponensial di atasnya.

Kantong token vs kantong yang mengalir

Dua algoritma mendominasi implementasi pembatasan laju. Memahami mana yang Anda hadapi memberi tahu Anda banyak hal tentang bagaimana API akan berperilaku saat menghadapi tekanan — dan algoritma mana yang harus Anda pilih saat membuat API Anda sendiri.

Kantong token

Kantong ini menampung hingga N token. Setiap permintaan mengonsumsi 1 token. Token mengisi kembali dengan laju tetap (misalnya 10 per detik). Jika kantong kosong, permintaan ditolak atau ditunda.

Tahanan lonjakan. Jika Anda belum membuat permintaan dalam waktu lama, Anda telah mengumpulkan token dan dapat mengirimkan lonjakan tanpa menabrak batas. API GitHub bekerja dengan cara ini — 5.000 permintaan per jam, tetapi Anda dapat menggunakan semuanya dalam satu kali jika Anda tidak mengakses API selama beberapa jam. Cocok untuk kasus interaktif di mana arus permintaan berfluktuasi.

Kantong yang mengalir

Permintaan dimasukkan ke dalam antrian dan mengalir keluar dengan laju tetap, terlepas dari kecepatan permintaan yang datang. Jika antrian penuh, permintaan baru akan dibatalkan.

Output yang halus, tidak ada lonjakan. Meskipun Anda masih memiliki kuota, permintaan mengalir secara perlahan sesuai dengan laju yang dikonfigurasi. Modul limit_req dalam Nginx menggunakan cara ini. Lebih baik untuk melindungi sistem downstream dari lonjakan — berguna untuk pengiriman webhook, panggilan API keluar, dan hal-hal lainnya di mana throughput yang dapat diprediksi lebih penting daripada toleransi lonjakan.

Mana yang harus dipilih saat Anda membuat API Anda sendiri: Ujung-ujung yang dihadapi oleh pengguna yang membutuhkan toleransi lonjakan → kantong token. Pengiriman webhook keluar atau panggilan API pihak ketiga → kantong yang mengalir. Tugas latar belakang di mana throughput yang halus penting → kantong yang mengalir.

Menghitung laju permintaan yang aman

Sebelum menulis logika pengulangan, tentukan apa yang benar-benar diizinkan. Jika API mengatakan "1.000 permintaan per jam", itu berarti 16,67 permintaan per menit atau 0,278 permintaan per detik. Tambahkan buffer keamanan 20% dan Anda akan mencapai sekitar 13 permintaan per menit — ruang yang cukup untuk menghindari masalah waktu ekstrem di mana dua jangkauan waktu saling tumpang tindih.

Gunakan Kalkulator Pembatasan Laju untuk mengonversi angka kuota menjadi laju per detik dan per menit, menemukan interval tidur yang tepat antara permintaan, dan melihat bagaimana tingkat konsekuensi memengaruhi risiko lonjakan.

Menerapkan pembatasan laju pada API Anda sendiri

Jika Anda berada di sisi lain dan ingin menambahkan perilaku 429 yang tepat pada API Anda sendiri:

  1. Pilih granulasi yang tepat. Per-IP mudah tetapi gagal untuk layanan yang berada di balik NAT atau penggunaan bersama. Per-API-key lebih baik tetapi membutuhkan autentikasi. Per-ID pengguna ideal jika Anda memiliki akses ke ID tersebut. Jangan campurkan granulasi tanpa tahu mana yang menang.
  2. Selalu kembalikan Retry-After. Kode 429 tanpa Retry-After mengharuskan setiap klien untuk mengimplementasikan heuristik pengulangan sendiri. Anda akan mendapatkan lebih banyak masalah kelompok, bukan penyelesaiannya.
  3. Gunakan Redis untuk pembatasan laju yang terdistribusi. Penandaan di memori tidak bekerja di antara berbagai instance server. Redis INCR + EXPIRE adalah pola standar. Bibliotek seperti rate-limiter-flexible (Node) dan slowapi (Python/FastAPI) mengabstraksi hal ini secara tepat.
  4. Catat setiap 429 yang Anda kirim. Peningkatan jumlah 429 dari satu kunci berarti ada bug pada klien atau penyalahgunaan yang sengaja. Kedua hal ini perlu diketahui secara real-time.
  5. Jangan batasi laju saat gagal autentikasi. Kembalikan kode 401 untuk kredensial yang salah, bukan kode 429. Menetapkan batas laju saat gagal autentikasi adalah cara Anda secara tidak sengaja memblokir pengguna Anda sendiri saat melakukan rotasi kredensial.

Apa yang harus dilakukan sekarang

Jika Anda mengalami kode 429:

  • Cek Retry-After pertama — gunakan jika tersedia, jangan ciptakan penundaan sendiri
  • Terapkan pengulangan eksponensial dengan gangguan acak — kode di atas siap untuk dipasang langsung
  • Catat header X-RateLimit-Remaining pada setiap respons — Anda mungkin menggunakan kuota lebih cepat daripada yang Anda pikirkan
  • Simpan respons di cache ketika data tidak berubah sering

Jika Anda membuat pembatasan laju: pilih library yang didukung Redis, kembalikan Retry-After pada setiap 429, pantau tingkat 429 per kunci, dan jangan batasi laju saat gagal autentikasi.

Kode 429 bukan musuh — itu adalah API yang memberi tahu Anda persis apa yang salah dan (biasanya) berapa lama Anda harus menunggu. Sebagian besar masalah pembatasan laju berasal dari mengabaikan pesan ini dan segera mengulang. Jangan lakukan itu.

Ingin bebas iklan? Bebas Iklan Hari Ini

Instal Ekstensi Kami

Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat

Ke Ekstensi Chrome Ke Ekstensi Tepi Ke Ekstensi Firefox Ke Ekstensi Opera

Papan Skor Telah Tiba!

Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!

IKLAN · HAPUS?
IKLAN · HAPUS?
IKLAN · HAPUS?

Pojok Berita dengan Sorotan Teknologi

Terlibat

Bantu kami untuk terus menyediakan alat gratis yang berharga

Belikan aku kopi
IKLAN · HAPUS?