Tutorials

Conexão Keep-Alive e HTTP/2 para chamadas de API CAPTCHA com menor latência

Reaproveitar a mesma conexão TCP entre o envio de um CAPTCHA e as consultas de resultado corta até 580 ms por resolução — sem mudar a lógica da sua integração, só a forma como o cliente HTTP é criado. Neste guia você configura:

  • Sessão persistente em Python com requests.Session
  • Cliente HTTP/2 multiplexado com httpx
  • Agentes keep-alive no Node.js com Axios

HTTP/2 ou keep-alive HTTP/1.1: qual escolher primeiro

Decida qual abordagem faz sentido antes de configurar:

Recurso HTTP/1.1 Keep-Alive HTTP/2
Reutilização de conexão Sim (sequencial) Sim (multiplexada)
Streams simultâneos 1 por conexão Até 100+ por conexão
Compressão de cabeçalho Não Compressão HPACK
Redução de latência ~60% ~70%
Exige suporte do navegador Não Não (são chamadas de API)
Melhor para Resoluções sequenciais Resoluções paralelas

Um CAPTCHA por vez? O keep-alive de HTTP/1.1 já cobre quase todo o ganho. Vários em paralelo? Aí o HTTP/2 compensa o esforço extra.

Quanto um handshake TCP novo custa em cada resolução

Resolver um reCAPTCHA v2 típico exige uma sequência fixa de chamadas à API:

  • 1 requisição de envio para in.php
  • 4 a 6 requisições de consulta (polling) para res.php
  • Total: 5 a 7 requisições HTTP por resolução

Sem reaproveitar a conexão, cada requisição paga um handshake TCP e uma negociação TLS do zero. Com keep-alive, só a primeira paga esse custo — as demais reaproveitam o socket já aberto:

Sem keep-alive Com keep-alive
Cálculo 5 × (TCP ~50 ms + TLS ~100 ms) 1 × (TCP + TLS, ~150 ms) + 4 × (reuso, ~5 ms)
Overhead total 750 ms 170 ms

Economia: ~580 ms por resolução. Rodando 10.000 resoluções por dia, isso equivale a 1,6 hora de latência que deixa de ser desperdiçada em handshakes repetidos.

Isso pesa mais para quem roda workers fora dos EUA e da Europa: em sa-east-1 (São Paulo), o RTT-base até o endpoint já é mais alto, e cada handshake extra multiplica esse custo.

Três formas de manter a conexão viva

A lógica de envio e consulta não muda — só a forma como o cliente HTTP é criado e reaproveitado.

Passo 1: Python com requests.Session

A biblioteca requests já reaproveita conexões TCP por padrão quando você usa um objeto Session — não é preciso nenhuma configuração extra além de criar a sessão uma vez e reutilizá-la em todas as chamadas:

# 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]}...")

O ponto-chave é criar session uma única vez, fora do loop de resolução. Cada chamada a solve_captcha() reaproveita o mesmo socket TCP em vez de abrir um novo a cada envio ou consulta.

Passo 2: HTTP/2 multiplexado com httpx

Para multiplexar várias resoluções sobre a mesma conexão física, troque requests por httpx com http2=True:

# 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()

Com HTTP/2, o cliente consegue enviar várias requisições em paralelo em um único socket, sem esperar a resposta de uma para disparar a próxima. É essa característica que faz diferença quando você resolve vários CAPTCHAs ao mesmo tempo.

Passo 3: Node.js com Axios e keep-alive

No Node.js, o keep-alive não vem ativado por padrão nos agentes HTTP nativos. Configure http.Agent e https.Agent com keepAlive: true e reaproveite-os em uma única instância do 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();
})();

Assim como em Python, crie httpAgent, httpsAgent e a instância api uma única vez fora do loop, e chame destroy() só ao finalizar a aplicação — não a cada lote.

Erros comuns de keep-alive e HTTP/2 (e como corrigir)

Problema Causa provável Correção
Conexão fecha entre uma consulta e outra Timeout do servidor ou de um proxy no meio do caminho Configure o timeout de keep-alive para mais de 30 s no cliente
Nenhum ganho perceptível de latência Sua biblioteca já usa keep-alive por padrão Confirme com uma ferramenta de monitoramento de rede (ex.: curl -v)
Erro de conexão recusada Pool de conexões esgotado Aumente maxSockets ou reduza a simultaneidade
HTTP/2 não é negociado Servidor não oferece suporte a h2 nessa rota Volte para keep-alive em HTTP/1.1
Latência alta mesmo com keep-alive ativo RTT alto entre a sua região e o endpoint da API Isso é geografia, não configuração — o keep-alive segue eliminando os handshakes repetidos, só não remove o RTT-base da rota

Para confirmar suporte a h2 antes de suspeitar do seu cliente, use openssl s_client -alpn h2 -connect ocr.captchaai.com:443.

Como dimensionar o pool de conexões pela sua simultaneidade

Ajuste o tamanho do pool à quantidade de resoluções que rodam ao mesmo tempo:

Resoluções simultâneas Tamanho de pool recomendado
1–5 5 conexões
5–20 10 conexões
20–50 25 conexões
50–100 50 conexões
Mais de 100 Use HTTP/2 (1 conexão)

Pool grande demais desperdiça memória; pool pequeno demais anula o ganho do keep-alive ao forçar conexões novas o tempo todo.

Perguntas frequentes

Dúvidas comuns sobre keep-alive e HTTP/2 na API da CaptchaAI.

Keep-alive reduz o número de threads que meu plano consome?

Não. Keep-alive reduz o handshake, não o número de threads. A CaptchaAI cobra por thread simultânea, com resoluções ilimitadas por thread. No plano BASIC (US$ 15/mês, 5 threads), keep-alive ajuda cada thread a processar mais resoluções por minuto, mas o número contratado continua o mesmo.

HTTP/2 muda o formato do JSON retornado por in.php e res.php?

Não. HTTP/2 atua na camada de transporte: negociação, multiplexação de streams e compressão de cabeçalhos com HPACK. O corpo da resposta de in.php e res.php continua o mesmo JSON de sempre — o parsing no seu código não precisa mudar.

O endpoint da CaptchaAI aceita HTTP/2?

Teste com curl --http2 https://ocr.captchaai.com/res.php. Se o servidor negociar h2, seu cliente HTTP/2 já se beneficia automaticamente. Caso contrário, use keep-alive em HTTP/1.1 — o ganho de latência ainda é real, só menor.

Compensa configurar HTTP/2 se eu resolvo um CAPTCHA por vez?

Pouco. Sem resoluções em paralelo, não existe o que multiplexar em várias streams simultâneas — o keep-alive em HTTP/1.1 já cobre praticamente todo o ganho disponível. Reserve o HTTP/2 para quando você realmente processa vários CAPTCHAs ao mesmo tempo.

Preciso encerrar a sessão HTTP entre lotes de resolução?

Não. Mantenha a sessão ou o cliente aberto entre lotes se você roda resoluções periódicas. Encerre a conexão apenas quando a aplicação for finalizada — abrir e fechar a cada lote reintroduz o custo do handshake que o keep-alive existe para eliminar.

Artigos relacionados

Próximas etapas

Elimine a sobrecarga de conexão em cada resolução — obtenha sua chave de API da CaptchaAI.

Guias relacionados:

Os comentários estão desativados para este artigo.