Skip to content

Satu API Key Cuma Bikin Riset Berhenti di 429

Adityo Guni Waluyo

Rate limit 429 bikin pipeline riset berhenti. Pelajaran merancang rotasi multi-key: cooldown per status HTTP, single-pass, dan error yang jangan dirotasi.

Ringkasan

Satu API key berarti satu batas rate limit, jadi patch ini merotasi beberapa key dengan cooldown berbeda: 429 ditunggu 60 detik, 402 lebih lama, error request seperti 400 dan 404 tidak dirotasi. Rotasinya single-pass agar tidak hang saat semua key cooldown. Rotasi bukan pengganti backoff; rapikan pola request dulu.

Pipeline riset artikel saya mencandung satu layanan eksternal buat mengambil isi halaman. Suatu sore, semua job mendadak berhenti dengan status 429 dari server. Rate limit. Dugaan pertama saya dangkal: tambah jeda antar request, urusan beres. Ternyata jeda cuma memundurkan jam ketika semuanya macet lagi. Satu key berarti satu batas, dan batas itu kepentok pas justru lagi butuh-butuhnya.

Cooldown Beda-Beda Tergantung Dosa

Jawaban vendor buat 429 jelas: mundur dulu, dan kalau ada header Retry-After, hormati durasinya [8]. Di tabel error-nya juga kelihatan 402 itu soal kredit habis, dan statusnya nggak retryable [8]. Dua makna yang beda jauh. Rate limit boleh dicoba lagi dalam hitungan detik sampai menit; kredit habis nggak akan sembuh dengan nyoba lagi lima menit kemudian.

Makanya patch yang saya pasang nggak pakai waktu tunggu seragam. Class _RotatingKeyFirecrawlClient di plugins/web/firecrawl/provider.py nyimpen cooldown berbeda per status: 429 dicatat 60 detik, 402 dicatat 300 detik, 401 dan 403 dicatat satu jam, sementara error jaringan cukup 30 detik. Angka-angka ini keputusan desain, bukan rekomendasi vendor; yang dari vendor cuma prinsip hormati Retry-After [8].

Daftar pengecualian justru bagian yang paling saya suka. Error 400, 404, dan 422 dilempar langsung tanpa rotasi. Logikanya sederhana: itu error soal request, bukan soal key. Ganti kunci buat payload yang salah itu cuma pindah masalah. Deteksi apa yang layak dirotasi dan apa yang nggak, itu yang membedakan failover dengan perpindahan masalah.

Loop Tanpa Batas Itu Hang Yang Manis

Desain pertama yang kebayang biasanya: loop terus sampai ketemu key yang sehat. Tapi ada jebakan halus di situ. Pas semua key lagi cooldown, pemilih key bisa balikin key yang sama terus, dan loop nggak akan pernah selesai. Prosesnya hidup, log berputar, tapi nggak ada kemajuan. Karena itu rotasinya dibikin single-pass: satu request boleh nyoba tiap key tepat satu kali. Habis itu, exception terakhir dilempar ke atas dan biar pemanggil yang memutuskan. Gagal cepat lebih jujur daripada berputar tanpa arah.

Cara jalaninnya: isi environment variable FIRECRAWL_API_KEYS dengan daftar key dipisah koma. Key tunggal lama tetap dihormati, jalurnya nggak disentuh. State rotasi, key aktif terakhir sama catatan cooldown, dilindungi threading.Lock, primitive lock paling bawaan di Python [10]. HTTPStatusError dari httpx, yang muncul pas response balikin status 4xx atau 5xx dari raise_for_status [9], jadi sinyal buat ngisi cooldown; sisanya, yang termasuk keluarga HTTPError [9], dianggap gangguan jaringan.

Satu lapisan lagi yang bikin patch ini tahan lama: dia idempoten. Sebelum nyentuh file, dia ngecek marker sudah ada apa belum. Tiap penggantian nempel di satu anchor yang dihitung harus persis satu di file asli, dan hasil akhirnya di-compile buat memastikan nggak ada sintaks yang rusak. Patch yang nggak bisa jalan dua kali tanpa merusak itu bom waktu buat sendiri.

Opini saya soal ini tegas: rotasi key itu bukan pengganti backoff yang benar, cuma penambah ambang. Pola request yang boros tetap boros, sekarang cuma bisa berdiri di atas beberapa dompet sekaligus. Rapikan dulu cara sistem meminta, baru rotasi jadi jaring pengaman yang pantas disebut jaring.

Sumber