Se a automação parece lenta mesmo com o CAPTCHA resolvido, o problema quase nunca está no solucionador. Está em como sua aplicação envia a tarefa, espera na fila e consulta o resultado.
Da latência total da chamada, só o tempo de execução do solucionador foge do seu controle — o resto dá para otimizar.
Latência esperada por tipo de CAPTCHA
| Tipo de CAPTCHA | Limite oficial (SLA) | Alcançável na prática |
|---|---|---|
| Imagem/OCR | < 0,5 s | 0,2–0,4 s |
| reCAPTCHA v2 | < 60 s | 10–20 s |
| reCAPTCHA v3 | < 4 s | 1–3 s |
| Cloudflare Turnstile | < 10 s | 4–8 s |
| GeeTest v3 | < 12 s | 6–10 s |
A coluna da direita já reflete as otimizações abaixo. Worker longe do destino? Meça o RTT primeiro — em
sa-east-1(São Paulo), a região costuma valer mais do que compensar distância com polling.
1. Troque o intervalo fixo de polling por um adaptativo
O intervalo padrão de 5 s desperdiça tempo quando a resolução termina entre duas consultas.
A saída é o polling adaptativo: comece rápido e vá espaçando.
Python
import time
import requests
API_KEY = "YOUR_API_KEY"
RESULT_URL = "https://ocr.captchaai.com/res.php"
def adaptive_poll(task_id, timeout=120):
"""Start polling at 3s, increase to 5s after 4 polls."""
start = time.time()
interval = 3 # start aggressive
polls = 0
while time.time() - start < timeout:
time.sleep(interval)
polls += 1
resp = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1"
}).json()
if resp["status"] == 1:
elapsed = time.time() - start
print(f"Solved in {elapsed:.1f}s ({polls} polls)")
return resp["request"]
if resp["request"] != "CAPCHA_NOT_READY":
raise Exception(resp["request"])
# Back off after initial fast polls
if polls >= 4:
interval = 5
raise TimeoutError(f"Task {task_id} timed out")
JavaScript
async function adaptivePoll(taskId, apiKey, timeout = 120000) {
const start = Date.now();
let interval = 3000;
let polls = 0;
while (Date.now() - start < timeout) {
await new Promise(r => setTimeout(r, interval));
polls++;
const resp = await fetch(
`https://ocr.captchaai.com/res.php?key=${apiKey}&action=get&id=${taskId}&json=1`
);
const data = await resp.json();
if (data.status === 1) {
console.log(`Solved in ${((Date.now() - start) / 1000).toFixed(1)}s (${polls} polls)`);
return data.request;
}
if (data.request !== 'CAPCHA_NOT_READY') {
throw new Error(data.request);
}
if (polls >= 4) interval = 5000;
}
throw new Error(`Task ${taskId} timed out`);
}
Na prática:
- Por tarefa: 1 a 4 s a menos que o intervalo fixo de 5 s.
- Em volume: pouco por chamada, mas some rápido num pipeline com muitas tarefas.
2. Corte a latência de conexão com pooling HTTP
Cada conexão HTTP nova paga de novo o custo do handshake TCP/TLS.
Reaproveitar a mesma sessão evita isso:
Python
session = requests.Session()
# Use session.get() and session.post() instead of requests.get/post
# The session reuses TCP connections automatically
JavaScript (Node.js)
const { Agent } = require('http');
const axios = require('axios');
const client = axios.create({
httpAgent: new Agent({ keepAlive: true, maxSockets: 10 }),
timeout: 10000,
});
// Use client.get() and client.post() for all API calls
O ganho:
- Por requisição: 50 a 100 ms, ignorando o handshake.
- Em volume: milhares de consultas por hora viram tempo de fila real economizado.
3. Elimine a espera com prefetch de CAPTCHA
A forma mais eficaz de esconder a latência do solucionador é não esperar por ela.
Envie a próxima tarefa enquanto ainda processa a atual:
from concurrent.futures import ThreadPoolExecutor
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
def prefetch_submit(sitekey, page_url):
resp = session.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url,
"json": "1",
})
data = resp.json()
if data["status"] == 1:
return data["request"]
raise Exception(data["request"])
# Submit next page's CAPTCHA while processing current page
with ThreadPoolExecutor(max_workers=2) as pool:
# Submit CAPTCHA for page 2 while processing page 1
future_task = pool.submit(prefetch_submit, "6Le-SITEKEY", "https://example.com/page/2")
# Process page 1...
process_page(current_data)
# Now get the pre-submitted task ID and poll
task_id = future_task.result()
token = adaptive_poll(task_id)
Esse padrão sobrepõe resolução e processamento: a latência percebida cai a quase zero, porque o token já está pronto quando você precisa dele.
4. Escolha o método certo para cada cenário
Em alguns cenários, a CaptchaAI aceita variações que chegam mais rápido ao token:
- reCAPTCHA v2 com callback conhecido:
userrecaptchacompingback(URL de callback) em vez de polling. - CAPTCHA de imagem só com dígitos:
base64comnumeric=1em vez de alta resolução.
5. Pule o proxy quando não for necessário
Rotear pelo proxy adiciona um salto de rede extra.
- Pule: na maioria dos casos, quando o site não exige um IP específico.
- Use: só quando o site de destino exigir requisições de um IP específico.
Exemplo dos dois casos:
# Without proxy — faster for most use cases
data = {
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url,
"json": "1",
}
# With proxy — only when required
data["proxy"] = "user:pass@1.2.3.4:8080"
data["proxytype"] = "HTTP"
6. Elimine a latência do polling com callback (pingback)
Dá para eliminar o polling por completo com o parâmetro pingback:
resp = session.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url,
"json": "1",
"pingback": "https://your-server.com/captcha-callback",
})
A CaptchaAI envia o resultado direto para sua URL quando a resolução termina — sem ciclo de consulta. É o método de recuperação com menor latência disponível hoje.
7. Meça o ganho real com um benchmark
Antes de declarar vitória, meça: rode o mesmo lote e compare mediana e P95 — não só a média:
import statistics
def benchmark(solve_func, iterations=20):
times = []
for i in range(iterations):
start = time.time()
try:
solve_func()
times.append(time.time() - start)
except Exception:
pass
if times:
print(f"Samples: {len(times)}/{iterations}")
print(f"Mean: {statistics.mean(times):.1f}s")
print(f"Median: {statistics.median(times):.1f}s")
print(f"P95: {sorted(times)[int(len(times)*0.95)]:.1f}s")
print(f"Min: {min(times):.1f}s")
print(f"Max: {max(times):.1f}s")
Solução de problemas
- Latência do polling não muda — ainda usando
requests.get()sem sessão. Troque parasession.get(). - Tokens de prefetch expiram antes do uso — processamento demorando demais. Reduza a janela ou envie mais perto do uso.
- URL de callback nunca recebe dados — servidor não acessível a partir da CaptchaAI. Garanta URL pública e revise o firewall.
- Polling agressivo dispara rate limit — intervalo abaixo de 2 s. Mantenha o mínimo em 3 s.
Perguntas frequentes
Qual otimização traz o maior ganho isolado?
O prefetch. Ele sobrepõe resolução e processamento — a latência percebida cai a quase zero.
Um plano com mais threads reduz a latência de um único CAPTCHA?
Não diretamente. Threads controlam paralelismo, não a velocidade de cada solução — a latência por tarefa depende das técnicas deste guia.
Polling mais agressivo pode gerar rate limit?
Sim. Consultas abaixo de 2 s costumam esbarrar no limite de requisições. Comece em 3 s — o equilíbrio que menos aciona o rate limit.
Os tipos em beta (CaptchaFox, Friendly Captcha, Lemin) têm os mesmos tempos deste guia?
Ainda não há métricas publicadas para os tipos em beta. As técnicas se aplicam do mesmo jeito, mas evite citar um tempo específico.
Comece a otimizar a latência da sua integração
Obtenha sua chave de API em captchaai.com e aplique o polling adaptativo no primeiro endpoint.