Suavizar tus llamadas con el rate limiting
La API pública de CaptainDNS aplica dos capas de rate limiting: una por IP antes de la autenticación y una por clave con token bucket cuya capacidad depende del plan. Esta guia explica ambas capas y como escribir un cliente que las respete sin perder peticiones.
Dos capas de protección
Limite por IP pre-auth
Antes de leer la cabecera Authorization, un limitador en memoria restringe el trafico por IP origen. El valor por defecto son 120 peticiones por minuto y por IP, ajustable del lado CaptainDNS. Esta capa protege de ataques volumetricos y credential stuffing.
Si se excede, la respuesta es 429 RATE_LIMITED con Retry-After: 60. No se verifica ninguna clave ni se consume ningun credito.
Token bucket por clave
Una vez autenticada la clave, un token bucket persistente en Postgres gestiona el límite por clave. La capacidad depende del plan:
| Plan | Capacidad (tokens) | Recarga |
|---|---|---|
| Free | 10 | 10 tokens/min |
| Starter | 60 | 60 tokens/min |
| Pro | 500 | 500 tokens/min |
| Business | 1 000 | 1 000 tokens/min |
| Enterprise | 1 200 | 1 200 tokens/min |
Cada peticion autenticada consume un token. El bucket se recarga continuamente, por lo que no hay que esperar un tick completo de minuto para reintentar.
Un bucket vacio devuelve 429 RATE_LIMITED. La cabecera Retry-After contiene los segundos hasta el proximo token.
Cabeceras de respuesta
Cada respuesta pública posiciona estas cabeceras:
RateLimit-Policy: "default";q=60;w=60
X-RateLimit-Limit: 60
RateLimit-Policy: formato IETF draft, describe la politica.qes la capacidad del bucket,wla ventana en segundos.X-RateLimit-Limit: capacidad del bucket, identica aq.
X-RateLimit-Remaining no se emite en cada peticion: se posiciona a 0 solamente ante un rechazo 429 (la funcion PL/pgSQL que consume un token no devuelve el número de tokens restantes, y una lectura adicional tendria un coste de latencia injustificado). Dimensiona tu cliente basandote en la capacidad, la cabecera Retry-After y tus propias mediciones del lado cliente, no en un contador servidor en tiempo real.
Ante un 429, tendras ademas:
Retry-After: 12
X-RateLimit-Remaining: 0
El cliente debe respetar Retry-After y esperar al menos los segundos indicados antes de reintentar.
Estrategia de retry recomendada
El patron idiomatico para un cliente respetuoso es el backoff exponencial acotado:
- Cuenta los tokens del lado cliente a partir de
X-RateLimit-Limit. Manten tu propio bucket local para anticipar la saturacion antes de enviar la peticion. - Ante
429 RATE_LIMITED, leeRetry-Aftery espera al menos ese tiempo. - Si acumulas varios 429 seguidos, aplica un multiplicador: 2x, 4x, 8x con un techo de 60 segundos.
- Anade un jitter aleatorio de +/- 20 % para evitar que varios clientes reintenten a la vez.
- Limita el número total de reintentos (por ejemplo 5). Mas alla, registra como error.
delay = retryAfter + random(-0.2, 0.2) * retryAfter
for attempt in 1..5:
response = send(request)
if response.status != 429:
return response
retryAfter = response.header["Retry-After"] or delay * attempt
sleep(min(retryAfter, 60))
raise RateLimitExceeded
Estrategias para pipelines por lotes
Las integraciones que procesan grandes volumenes en batch se benefician de estrategias adicionales:
- Token bucket en el cliente: replica localmente el bucket del servidor y envia solo si hay un token disponible.
- Paralelizar segun la capacidad: un plan Pro permite 500 tokens/min, unos 8 req/s. Ejecutar 8 workers en paralelo es mas eficiente que un unico worker con sleeps.
- Separacion de endpoints caros: reparte las llamadas caras y las baratas en colas distintas.
- Ventanas de mantenimiento: algunos batchs pueden correr fuera de horas punta.
Que cuenta como peticion
Cada peticion HTTP autenticada consume un token, incluso si falla con 400 o 500. Excepciones:
429 RATE_LIMITEDno consume token.401 INVALID_API_KEYno toca el bucket por clave, pero cuenta en el límite por IP.403 IP_NOT_ALLOWEDno consume ni token ni credito.
Aumentar tu capacidad
La capacidad del token bucket es propiedad del plan. Para aumentarla, pasa al plan superior desde /account/billing; el efecto es inmediato. Los clientes Enterprise pueden negociar un techo personalizado hasta 5 000 req/min.
Diagnosticar un 429
Causas posibles:
- Bucket pre-auth: superas 120 req/min en una sola IP. Verifica que varios servicios no compartan el mismo egress (NAT, CGNAT).
- Token bucket por clave: tu plan no ofrece la capacidad necesaria.
- Pico puntual: un batch sin suavizado envio 200 peticiones en un segundo.
- Desfase de reloj: casos raros de servidores sin NTP.
Herramientas CaptainDNS relacionadas
- El DNS lookup permite verificar manualmente un registro sin consumir créditos.
- El DMARC monitoring agrega los informes DMARC sin pasar por la API pública.
Siguiente paso: la idempotencia para ahorrar créditos en reintentos, o los códigos de error.