Latensi solve CAPTCHA Anda mungkin bukan soal server CaptchaAI yang lambat — soal koneksi HTTP yang dibangun ulang tiap request. Satu solve reCAPTCHA v2 perlu submit ke in.php plus beberapa kali polling ke res.php; tiap koneksi baru berarti TCP handshake dan negosiasi TLS ekstra, 100–300 ms yang bisa dihindari. Berikut implementasi keep-alive dan HTTP/2 di Python dan Node.js untuk CaptchaAI.
Kenapa Ini Penting bagi Tim Scraping dan Data Indonesia
Overhead koneksi paling terasa di volume tinggi — agensi price monitoring, tim data e-commerce, freelancer scraping dari Upwork dan Fastwork yang menagih klien per volume job selesai. Job dari AWS ap-southeast-1 (Singapura) atau GCP asia-southeast2 (Jakarta) yang memanggil ocr.captchaai.com ribuan kali sehari cepat merasakan akumulasi latensi itu, terutama di jaringan mobile-first yang lebih sensitif terhadap round-trip ekstra.
CaptchaAI menagih per thread konkuren, bukan per request HTTP — jadi penghematan latensi di bawah ini menambah throughput per thread, bukan mengubah biaya bulanan Anda sama sekali.
Anatomi Overhead: dari Mana Asalnya 750 ms Itu
Solve reCAPTCHA v2 yang tipikal melibatkan beberapa panggilan berurutan:
- 1 submit request ke
in.php - 4–6 polling request ke
res.php - Total: 5–7 HTTP request
Setiap koneksi yang dibangun dari nol membayar TCP handshake dan negosiasi TLS penuh. Reuse koneksi memangkas biaya itu untuk semua request setelah yang pertama:
| Skenario | Perhitungan | Overhead total |
|---|---|---|
| Tanpa keep-alive | 5 × (TCP handshake ~50 ms + TLS ~100 ms) | ~750 ms |
| Dengan keep-alive | 1 × (TCP + TLS penuh) + 4 × (~5 ms reuse) | ~170 ms |
Selisihnya ~580 ms per solve. Untuk volume 10.000 solve/hari, itu setara 1,6 jam latensi yang hilang percuma — dan itu sebelum HTTP/2 masuk hitungan.
Python: Reuse Koneksi Otomatis dengan requests.Session
requests.get() tanpa objek Session membuka koneksi baru tiap panggilan. Ganti dengan Session dan koneksi TCP dipertahankan di seluruh request:
# keepalive_solver.py
import os
import time
import requests
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
# Create a session — reuses TCP connections across requests
session = requests.Session()
session.headers.update({"Connection": "keep-alive"})
def solve_captcha(sitekey, pageurl):
"""Solve reCAPTCHA v2 using a persistent connection."""
# Submit — uses existing connection if available
resp = session.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
# Poll — reuses the same connection
time.sleep(15)
for _ in range(25):
poll = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Solve multiple CAPTCHAs reusing the same connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
HTTP/2 di Python dengan httpx
requests tidak bicara HTTP/2 — pakai httpx kalau server target menegosiasikannya:
# http2_solver.py
import os
import time
import httpx
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
BASE_URL = "https://ocr.captchaai.com"
# HTTP/2 client with connection pooling
client = httpx.Client(http2=True, timeout=30.0)
def solve_captcha(sitekey, pageurl):
"""Solve using HTTP/2 multiplexed connections."""
resp = client.get(f"{BASE_URL}/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
time.sleep(15)
for _ in range(25):
poll = client.get(f"{BASE_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Multiple solves over a single HTTP/2 connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
client.close()
Node.js: axios dengan Agent Keep-Alive
axios tidak mengaktifkan keep-alive secara default — pasang http.Agent dan https.Agent sendiri lalu ikat ke instance axios:
// keepalive_solver.js
const axios = require('axios');
const http = require('http');
const https = require('https');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
// Create agents with keep-alive enabled
const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 });
const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 });
// Axios instance with persistent connections
const api = axios.create({
baseURL: 'https://ocr.captchaai.com',
httpAgent,
httpsAgent,
timeout: 30000,
});
async function solveCaptcha(sitekey, pageurl) {
// Submit — reuses connection
const submit = await api.get('/in.php', {
params: {
key: API_KEY, method: 'userrecaptcha',
googlekey: sitekey, pageurl, json: '1',
},
});
if (submit.data.status !== 1) throw new Error(submit.data.request);
const taskId = submit.data.request;
// Poll — reuses same connection
await new Promise(r => setTimeout(r, 15000));
for (let i = 0; i < 25; i++) {
const poll = await api.get('/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: '1' },
});
if (poll.data.status === 1) return poll.data.request;
if (poll.data.request !== 'CAPCHA_NOT_READY') throw new Error(poll.data.request);
await new Promise(r => setTimeout(r, 5000));
}
throw new Error('Timeout');
}
(async () => {
for (let i = 0; i < 5; i++) {
const token = await solveCaptcha(
'6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'https://www.google.com/recaptcha/api2/demo'
);
console.log(`Solve ${i + 1}: ${token.slice(0, 30)}...`);
}
// Clean up agents
httpAgent.destroy();
httpsAgent.destroy();
})();
Menentukan Ukuran Connection Pool yang Tepat
Sesuaikan ukuran pool dengan concurrency nyata yang benar-benar Anda jalankan hari ini, bukan angka teoretis yang mungkin baru tercapai bulan depan:
| Solve concurrent | Ukuran pool yang disarankan |
|---|---|
| 1–5 | 5 koneksi |
| 5–20 | 10 koneksi |
| 20–50 | 25 koneksi |
| 50–100 | 50 koneksi |
| 100+ | Gunakan HTTP/2 (1 koneksi) |
Pool terlalu besar membuang memori untuk koneksi menganggur; pool terlalu kecil memaksa koneksi baru terus-menerus dan meniadakan manfaat keep-alive dari awal.
HTTP/2 atau Cukup HTTP/1.1 Keep-Alive?
| Fitur | HTTP/1.1 Keep-Alive | HTTP/2 |
|---|---|---|
| Reuse koneksi | Ya (sekuensial) | Ya (multipleks) |
| Aliran concurrent | 1 per koneksi | Hingga 100+ per koneksi |
| Kompresi header | Tidak | Kompresi HPACK |
| Pengurangan latensi | ~60% | ~70% |
| Browser diperlukan | Tidak | Tidak (API call) |
| Terbaik untuk | Solve sekuensial | Solve paralel |
Solve satu per satu? HTTP/1.1 keep-alive sudah memadai, tidak perlu upgrade. Solve paralel dalam jumlah besar? HTTP/2 menang karena semua stream berbagi satu koneksi tanpa harus antre giliran.
Troubleshooting: Kenapa Koneksi Anda Belum Terasa Lebih Cepat
- Koneksi tutup antar polling — biasanya timeout server atau proxy; set timeout
keep-aliveclient Anda di atas 30 detik. - Tidak ada peningkatan performa — keep-alive mungkin sudah aktif secara default di library Anda; verifikasi dengan network monitoring tool, jangan asumsi.
- Error koneksi ditolak — pool Anda habis; naikkan
maxSocketsatau kurangi concurrency yang berjalan bersamaan. - HTTP/2 tidak dinegosiasikan — server tidak mendukung h2; client Anda otomatis kembali ke HTTP/1.1 keep-alive sebagai fallback.
Pertanyaan Umum
Apakah requests.Session dan axios sudah keep-alive secara default?
Sebagian. requests.Session otomatis mengelola pooling, tapi requests.get() tanpa Session tetap buka koneksi baru tiap kali. axios tidak mengaktifkan keep-alive sendiri — pasang http.Agent/https.Agent dengan keepAlive: true.
Berapa connection pool yang ideal untuk job scraping paralel?
Sesuaikan dengan tabel di atas dan concurrency nyata, bukan kapasitas maksimum akun. Di atas 100 koneksi paralel, HTTP/2 multiplexing lebih efisien daripada menambah pool HTTP/1.1.
Apakah endpoint in.php dan res.php CaptchaAI mendukung HTTP/2?
Uji dengan curl --http2 https://ocr.captchaai.com/res.php. Jika server menegosiasikan h2, client HTTP/2 Anda langsung dapat manfaatnya; jika tidak, HTTP/1.1 keep-alive tetap fallback yang solid.
Apakah reuse koneksi memengaruhi biaya thread CaptchaAI?
Tidak. CaptchaAI menagih per thread konkuren, bukan jumlah request HTTP. Keep-alive dan HTTP/2 memangkas latensi jaringan — solve yang selesai lebih cepat membuat thread lebih cepat bebas, jadi throughput per thread naik.
Apakah proxy SOCKS5 saya tetap bisa mempertahankan keep-alive?
Tergantung implementasinya. Sebagian proxy SOCKS5 menutup koneksi tiap request meski client Anda mengaktifkan keep-alive. Pantau koneksi TCP aktif — kalau naik-turun mengikuti tiap request, proxy Anda tidak mempertahankan sesi persisten.
Artikel Terkait
Pelajari juga pola Circuit Breaker untuk panggilan API CAPTCHA untuk menangani error di sisi retry, dan benchmark waktu solve CAPTCHA CaptchaAI untuk data performa per tipe CAPTCHA.
Langkah Selanjutnya
Setiap milidetik yang Anda hemat di lapisan koneksi menambah throughput solve — ambil API key CaptchaAI Anda.