¿La resolución DNS ralentiza tu API de resolución de CAPTCHA? Casi siempre no. Con keep-alive, el host se resuelve una vez y la conexión reutiliza esa IP en cada llamada a ocr.captchaai.com. El DNS solo pesa cuando abres conexiones nuevas por solicitud o no hay caché, y ahí añade entre 5 y 200 ms por llamada.
Regla general: si ya usas conexiones persistentes, olvídate del DNS. Vigílalo solo en arranques en frío serverless, con un resolver de ISP lento o una conexión por solicitud.
¿Cuándo es el DNS un cuello de botella real?
Cuatro escenarios, todos con lo mismo: no reutilizan la conexión y resuelven el host una y otra vez.
- Conexiones nuevas por solicitud: sin
Session(Python) ni agente keep-alive (Node.js). - Arranques en frío en serverless o contenedores: la instancia nueva no tiene DNS en caché.
- Resolvers DNS lentos: DNS de ISP por defecto, sin caché local.
- Muchos workers arrancando a la vez: decenas de procesos resuelven el mismo host en paralelo.
Cuánta latencia añade cada búsqueda DNS
Una resolución de CAPTCHA son 5–7 solicitudes HTTP (1 envío y 4–6 consultas). Con una búsqueda DNS lenta en cada una, el coste se dispara:
| Escenario | Búsquedas DNS | Latencia agregada |
|---|---|---|
| Sin caché, DNS lento (200 ms por búsqueda) | 7 | 1.400 ms |
| Caché DNS del sistema operativo (solo primera llamada) | 1 | 200 ms |
| Keep-alive activo (0 búsquedas nuevas) | 0 | 0 ms |
| Pre-resolución DNS + keep-alive | 0 | 0 ms |
Lo importante: con HTTP keep-alive, la conexión TCP reutiliza la IP resuelta y el DNS deja de contar; solo pesa con conexiones nuevas por solicitud.
DNS en entornos serverless y contenedores
Aquí el DNS sí puede doler. Una función AWS Lambda —por ejemplo en São Paulo, cerca de tus usuarios— con el DNS por defecto repite la búsqueda en cada arranque en frío; pre-resolverla en la init la saca del camino crítico.
| Entorno | Comportamiento de la caché DNS | Recomendación |
|---|---|---|
| AWS Lambda | En caché en el contexto de ejecución; se pierde en arranque en frío | Pre-resolución en el handler init |
| Google Cloud Functions | En caché dentro de la instancia | Pre-resolución en el ámbito global |
| Docker | Usa el DNS del host por defecto | Configura --dns 1.1.1.1 |
| Kubernetes | CoreDNS con caché configurable | Establece ndots: 1 en el DNS del pod |
Diagnóstico rápido de DNS
| Problema | Causa | Solución |
|---|---|---|
| Primera llamada lenta, las demás rápidas | Búsqueda DNS en la primera llamada | Normal con la caché del SO; usa keep-alive |
| Todas las llamadas lentas (+100 ms) | Sin caché DNS, resolución lenta | Configura el DNS en 1.1.1.1 o 8.8.8.8 |
| Picos de latencia aleatorios | Expiración del TTL de la caché DNS | Aumenta el TTL local o usa pre-resolución |
| Arranque en frío de contenedor lento | Sin DNS en caché en la instancia nueva | Pre-resolución en el código de inicialización |
Optimizar el DNS en Python
Mide primero cuánto tarda tu resolución DNS
Antes de optimizar, mide. Este fragmento compara la primera resolución (sin caché) con la segunda (en caché):
import socket
import time
# Measure DNS resolution time
hostname = "ocr.captchaai.com"
start = time.time()
ip = socket.getaddrinfo(hostname, 443)
first_resolve = time.time() - start
start = time.time()
ip = socket.getaddrinfo(hostname, 443)
second_resolve = time.time() - start
print(f"First resolve: {first_resolve*1000:.1f}ms")
print(f"Second resolve: {second_resolve*1000:.1f}ms (OS cached)")
Pre-resuelve el host y reutiliza la conexión
La combinación ganadora: pre-resolver el host una vez y reutilizarlo con un Session, para que el DNS se resuelva al arrancar.
import os
import socket
import requests
from urllib3.util.connection import create_connection
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
# Pre-resolve the API hostname
CAPTCHAAI_IP = socket.getaddrinfo("ocr.captchaai.com", 443)[0][4][0]
print(f"Resolved ocr.captchaai.com to {CAPTCHAAI_IP}")
# Patch connection to use cached IP
DNS_CACHE = {"ocr.captchaai.com": CAPTCHAAI_IP}
class CachedHTTPAdapter(requests.adapters.HTTPAdapter):
def send(self, request, **kwargs):
return super().send(request, **kwargs)
# Use with Session for fastest resolution
session = requests.Session()
session.headers.update({"Connection": "keep-alive"})
# The session already maintains keep-alive, so DNS is resolved once
# For the first request, the OS cache handles subsequent lookups
resp = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "getbalance", "json": "1",
})
print(f"Balance: {resp.json()}")
Elige un resolver DNS con menor latencia
Si controlas el sistema, usa un DNS público rápido y mídelo desde tu región:
# For systems where you control DNS configuration:
# /etc/resolv.conf (Linux) or system DNS settings
# Recommended: Cloudflare (1.1.1.1) or Google (8.8.8.8)
# In Python, you can also use dnspython for explicit resolution
import dns.resolver
resolver = dns.resolver.Resolver()
resolver.nameservers = ["1.1.1.1", "8.8.8.8"]
answers = resolver.resolve("ocr.captchaai.com", "A")
for answer in answers:
print(f"Resolved: {answer}")
Optimizar el DNS en Node.js
Mide la resolución DNS
Igual en Node.js: aísla la primera búsqueda de la segunda, ya en caché.
const dns = require('dns');
const { performance } = require('perf_hooks');
const hostname = 'ocr.captchaai.com';
// First resolution
const start1 = performance.now();
dns.lookup(hostname, (err, address) => {
const time1 = performance.now() - start1;
console.log(`First resolve: ${time1.toFixed(1)}ms → ${address}`);
// Second resolution (OS cached)
const start2 = performance.now();
dns.lookup(hostname, (err2, address2) => {
const time2 = performance.now() - start2;
console.log(`Second resolve: ${time2.toFixed(1)}ms → ${address2}`);
});
});
Pre-resolución con agente keep-alive
Combina la pre-resolución con un agente keepAlive: true en Axios: el DNS se resuelve una vez y se reutiliza el pool de sockets.
const dns = require('dns');
const https = require('https');
const axios = require('axios');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
// Pre-resolve and cache
let cachedIP = null;
async function preResolve() {
return new Promise((resolve, reject) => {
dns.lookup('ocr.captchaai.com', (err, address) => {
if (err) reject(err);
cachedIP = address;
console.log(`Cached IP: ${cachedIP}`);
resolve(address);
});
});
}
// Use keep-alive agent (DNS resolved once per connection)
const agent = new https.Agent({
keepAlive: true,
maxSockets: 20,
keepAliveMsecs: 60000,
});
const api = axios.create({
baseURL: 'https://ocr.captchaai.com',
httpsAgent: agent,
timeout: 30000,
});
(async () => {
await preResolve();
const resp = await api.get('/res.php', {
params: { key: API_KEY, action: 'getbalance', json: '1' },
});
console.log(`Balance: ${resp.data}`);
})();
Preguntas frecuentes
¿Cómo sé si el DNS es mi cuello de botella y no la red o la API?
Mídelo con el script de arriba: si solo la primera llamada es lenta, es la búsqueda DNS inicial; si todas lo son, el problema es la red o el resolver, no el CAPTCHA.
¿El keep-alive elimina por completo las búsquedas DNS?
En la práctica, sí, mientras la conexión siga viva: la IP se reutiliza durante toda la conexión TCP y solo se resuelve de nuevo al expirar el keep-alive.
¿El DNS afecta al tiempo de resolución del CAPTCHA o solo a la latencia de red?
Solo a la latencia de red de tus llamadas. El tiempo que CaptchaAI tarda en resolver el CAPTCHA no cambia; reduces el ida y vuelta HTTP.
Guías relacionadas
- Conexiones keep-alive y HTTP/2 en la API de CAPTCHA
- Cómo medir los tiempos de resolución con CaptchaAI
- Optimización de la latencia de la API de CaptchaAI