ERROR_NO_SLOT_AVAILABLE bukan tanda akun Anda bermasalah — itu CaptchaAI menolak task baru karena thread concurrent pada paket Anda sedang penuh semua. Begini cara mengenali batas mana yang sebenarnya Anda langgar, lalu memperbaikinya dengan semaphore, retry backoff, task queue, dan polling yang lebih hemat, sebelum buru-buru upgrade paket yang belum tentu perlu.
Aturan cepatnya:
ERROR_NO_SLOT_AVAILABLEselalu soal jumlah thread yang terpakai bersamaan. HTTP 429 selalu soal kecepatan Anda memanggil API, termasuk saat polling. Dua masalah, dua perbaikan berbeda.
Dua Rate Limit CaptchaAI: Thread Concurrent vs Kecepatan Request
Batas task concurrent Anda mengikuti paket yang aktif, bukan angka tetap untuk semua akun — sama dengan jumlah thread pada paket itu. Batas request rate berlaku terpisah, per akun, tidak peduli paketnya apa:
| Jenis batas | Yang dikontrol | Error yang muncul |
|---|---|---|
| Task concurrent | Jumlah task yang sedang diselesaikan secara bersamaan | ERROR_NO_SLOT_AVAILABLE |
| Request rate | Jumlah panggilan API per detik ke endpoint submit/poll | HTTP 429 |
Satu thread menampung satu task yang sedang diselesaikan; begitu task selesai, thread langsung bebas dipakai task berikutnya.
Kenali Dulu Gejalanya, Baru Cari Perbaikannya
Empat pola gejala berikut mencakup hampir semua tiket yang masuk soal batas concurrent:
| Yang terlihat | Kemungkinan penyebab |
|---|---|
| Sebagian task berhasil, sebagian gagal di waktu bersamaan | Anda sesekali menyentuh batas thread concurrent |
| Waktu solve makin lama padahal jumlah task tetap | Antrean menumpuk di sisi akun Anda |
ERROR_NO_SLOT_AVAILABLE hanya muncul saat jam sibuk |
Proses lain di akun yang sama ikut memakai thread |
| HTTP 429 muncul walau task concurrent Anda sedikit | Loop polling terlalu rapat, bukan soal thread |
Berapa Thread yang Anda Punya? Cek Dulu Sebelum Ubah Kode
Untuk tim yang baru mengukur kebutuhan concurrency-nya, titik awal yang wajar:
- BASIC ($15/bulan, 5 thread) — cukup untuk uji coba atau volume kecil.
- STANDARD ($30/bulan, 15 thread) — titik awal umum untuk tim scraping atau otomatisasi lepasan yang sudah jalan di produksi skala kecil.
- ADVANCE ($90/bulan, 50 thread) — untuk beban paralel yang lebih berat, misalnya price-monitoring di puluhan domain sekaligus.
Kalau worker Anda tersebar lintas region — misalnya browser headless jalan di AWS ap-southeast-1 (Singapura) sementara server yang mengirim task ada di ap-southeast-3 (Jakarta) — latency jaringan menambah waktu tiap task menahan thread-nya. Artinya jumlah task paralel yang aman biasanya sedikit di bawah jumlah thread nominal Anda, bukan persis sama. Cek dashboard di captchaai.com untuk melihat alokasi thread paket Anda saat ini.
Perbaikan 1: Batasi Concurrency dengan Semaphore
Jangan biarkan kode Anda menembak task sebanyak-banyaknya tanpa kendali. Pasang semaphore yang menahan jumlah task paralel tepat di bawah batas thread akun Anda:
import requests
import time
import threading
API_KEY = "YOUR_API_KEY"
MAX_CONCURRENT = 20 # Stay below your account limit
semaphore = threading.Semaphore(MAX_CONCURRENT)
def solve_captcha(params):
"""Solve a CAPTCHA with concurrency control."""
with semaphore:
params["key"] = API_KEY
params["json"] = 1
submit = requests.post("https://ocr.captchaai.com/in.php", data=params).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit: {submit.get('request')}")
task_id = submit["request"]
time.sleep(10)
for _ in range(30):
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve: {result['request']}")
time.sleep(5)
raise TimeoutError("Timed out")
Kenapa MAX_CONCURRENT Perlu di Bawah Batas Nyata, Bukan Persis Sama
MAX_CONCURRENT di sini sengaja diset di bawah batas thread nyata Anda, bukan persis sama dengan angka di dashboard. Sisakan sedikit ruang untuk proses lain yang mungkin berjalan bersamaan di akun yang sama — dashboard, cron job lain, atau worker kedua yang lupa Anda matikan.
Perbaikan 2: Retry Otomatis Saat ERROR_NO_SLOT_AVAILABLE
Semaphore mengatur sisi kode Anda, tapi thread di akun bisa saja penuh sesaat karena proses lain. Daripada task langsung gagal, retry dengan jeda yang meningkat eksponensial (exponential backoff):
def submit_with_retry(params, max_retries=5):
"""Submit with automatic retry for slot errors."""
params["key"] = API_KEY
params["json"] = 1
for attempt in range(max_retries):
resp = requests.post("https://ocr.captchaai.com/in.php", data=params).json()
if resp.get("status") == 1:
return resp["request"]
error = resp.get("request", "")
if error == "ERROR_NO_SLOT_AVAILABLE":
wait = 2 ** attempt # Exponential backoff: 1, 2, 4, 8, 16 seconds
print(f"No slot available, retrying in {wait}s (attempt {attempt + 1})")
time.sleep(wait)
continue
else:
raise RuntimeError(f"Submit error: {error}")
raise RuntimeError("Max retries exceeded — no slots available")
Yang perlu Anda perhatikan dari pola ini:
- Menyerap lonjakan singkat tanpa membanjiri API dengan percobaan ulang yang justru memperparah antrean.
- Jeda naik otomatis tiap percobaan (1, 2, 4, 8, 16 detik) — bukan interval tetap.
- Error selain
ERROR_NO_SLOT_AVAILABLElangsung dilempar, tidak ikut di-retry buta.
Perbaikan 3: Pakai Task Queue, Jangan Kirim Semua Sekaligus
Kalau jumlah task yang harus diproses besar, menembakkannya semua ke API dalam satu waktu hanya memindahkan masalah dari kode Anda ke error CaptchaAI. Antrekan task, lalu proses dengan worker sejumlah MAX_CONCURRENT:
from queue import Queue
from threading import Thread
task_queue = Queue()
results = {}
def worker():
while True:
task_id_local, params = task_queue.get()
try:
token = solve_captcha(params)
results[task_id_local] = {"status": "ok", "token": token}
except Exception as e:
results[task_id_local] = {"status": "error", "message": str(e)}
finally:
task_queue.task_done()
# Start worker threads (limited by semaphore)
for _ in range(MAX_CONCURRENT):
t = Thread(target=worker, daemon=True)
t.start()
# Add tasks to queue
captcha_tasks = [
{"method": "userrecaptcha", "googlekey": "KEY1", "pageurl": "https://site1.com"},
{"method": "userrecaptcha", "googlekey": "KEY2", "pageurl": "https://site2.com"},
# ... more tasks
]
for i, params in enumerate(captcha_tasks):
task_queue.put((i, params))
task_queue.join()
print(f"Completed: {len(results)} tasks")
Pola ini juga memudahkan Anda melacak task mana yang gagal, tanpa kehilangan hasil task lain yang sudah selesai duluan.
Perbaikan 4: Kurangi Frekuensi Polling
Polling yang terlalu rapat membuang panggilan API dan bisa memicu HTTP 429 sendiri — masalah yang terpisah dari batas thread concurrent:
# WRONG — polling every 1 second
time.sleep(1)
# CORRECT — poll every 5 seconds
time.sleep(5)
# BETTER — wait longer on initial delay, then poll
time.sleep(15) # Initial wait
for _ in range(20):
# ... poll
time.sleep(5)
Aturan Praktis Interval Polling
Beri jeda awal sebelum polling pertama — solve jarang selesai dalam hitungan di bawah beberapa detik — lalu poll setiap 5 detik, bukan setiap detik. Ini mengurangi jumlah panggilan res.php per task secara signifikan tanpa membuat Anda menunggu lebih lama untuk hasil yang sebenarnya belum siap.
Pantau Jumlah Task Aktif Secara Real-Time
Sebelum menyalahkan batas akun, pastikan dulu kode Anda sendiri tidak diam-diam membuka lebih banyak task paralel dari yang Anda kira:
active_count = 0
lock = threading.Lock()
def track_solve(params):
global active_count
with lock:
active_count += 1
print(f"Active tasks: {active_count}/{MAX_CONCURRENT}")
try:
return solve_captcha(params)
finally:
with lock:
active_count -= 1
Log ini juga berguna untuk mencari MAX_CONCURRENT yang pas: naikkan pelan-pelan sampai ERROR_NO_SLOT_AVAILABLE mulai muncul, lalu turunkan sedikit dari titik itu.
Pertanyaan Umum
Ringkasan sebelum masuk detail — perbaikan mana untuk gejala mana:
| Gejala | Perbaikan yang relevan |
|---|---|
ERROR_NO_SLOT_AVAILABLE terus-menerus |
Perbaikan 1 (semaphore) + Perbaikan 3 (task queue) |
ERROR_NO_SLOT_AVAILABLE sesekali |
Perbaikan 2 (retry backoff) |
| HTTP 429 saat polling | Perbaikan 4 (kurangi frekuensi polling) |
Kenapa ERROR_NO_SLOT_AVAILABLE muncul padahal traffic saya tidak terlalu besar?
Penyebab paling sering: task lama tidak pernah "dilepas". Worker yang crash sebelum polling selesai bisa meninggalkan thread tertahan sampai timeout server. Cek apakah semua task Anda benar-benar mencapai status selesai atau timeout, bukan menggantung tanpa penanganan.
Berapa MAX_CONCURRENT yang aman untuk paket BASIC atau STANDARD saya?
Sebagai titik awal, set MAX_CONCURRENT sedikit di bawah jumlah thread paket Anda, lalu naikkan bertahap sambil memantau log task aktif dari bagian sebelumnya:
- BASIC (5 thread) → mulai dari
MAX_CONCURRENT = 4 - STANDARD (15 thread) → mulai dari
MAX_CONCURRENT = 12 - ADVANCE (50 thread) → mulai dari
MAX_CONCURRENT = 40
Apakah polling res.php ikut dihitung ke rate limit request?
Ya. Setiap request res.php dihitung sebagai satu panggilan API, sama seperti in.php. Poll setiap 5 detik, bukan setiap 1 detik, supaya tidak memicu HTTP 429 secara terpisah dari batas thread concurrent Anda.
Task saya sebagian berhasil dan sebagian gagal dengan error slot penuh — apakah ini wajar?
Ya, ini pola khas menyentuh batas secara sesekali, bukan terus-menerus. Task yang terkirim saat thread masih tersedia berhasil; task yang terkirim tepat saat semua thread penuh gagal. Retry dengan backoff (Perbaikan 2) menyelesaikan sebagian besar kasus ini tanpa perlu upgrade paket.
Bagaimana cara menambah batas thread concurrent saya?
Upgrade ke paket dengan alokasi thread lebih besar — lihat perbandingan paket di captchaai.com. Sebelum menambah biaya bulanan, cek dua hal dulu:
- Apakah lonjakan task Anda musiman, atau memang konsisten naik terus
- Apakah semaphore dan task queue di atas sudah benar-benar menyerap lonjakannya
Pilih Paket Thread CaptchaAI Sesuai Volume Concurrent Anda
Kalau ERROR_NO_SLOT_AVAILABLE tetap muncul setelah semaphore, retry, dan task queue terpasang rapi, itu sinyal jelas: paket Anda memang kekurangan thread, bukan masalah kode. Bandingkan paket dan alokasi thread di captchaai.com.