HTTP 429: interpretar Retry-After y reintentar sin saturar el servicio
HTTP 429 indica que el servidor está limitando solicitudes. Lee la respuesta y Retry-After, reduce el ritmo compartido y repite solo operaciones que sea seguro repetir. Define un plazo total y un máximo de intentos.
En esta guía
Una integración puede funcionar a mano y fallar al ejecutar un lote: varios trabajadores comparten la misma cuenta. El 429 describe la carga conjunta; reintentar todos a la vez agrava el problema.
Registra el diagnóstico y calcula el presupuesto de la cola. Las cifras siguientes pertenecen a un servicio imaginario; consulta siempre el contrato del proveedor.
Identifica quién devuelve el límite
Registra hora, ruta, método, estado, identificador de solicitud y cabeceras de espera; excluye credenciales y datos personales. Distingue entre API, proxy y CDN. El aspecto de la página de error no basta.
El límite puede corresponder a IP, usuario, aplicación o recurso. Una cuota diaria agotada no se recupera espaciando solicitudes durante unos segundos.
- ¿Aumentaron los trabajos o los reintentos?
- ¿Comparten la cuenta otras aplicaciones, pestañas o claves?
- ¿Se limita el número de solicitudes, las activas, los tokens u otro recurso?
- ¿Cabe la recuperación dentro del plazo del usuario?
Lee la unidad de Retry-After
Puede ser un entero no negativo en segundos o una fecha HTTP. El valor 12 significa 12 segundos, no milisegundos. Una fecha requiere un reloj fiable; una fecha pasada no justifica un bucle inmediato.
Respeta la demora mínima del servidor y añade dispersión aleatoria. Si supera el plazo del trabajo, detén o reprograma la operación; no reduzcas esa espera a un máximo local menor.
| Observación | Significado | Acción |
|---|---|---|
| Retry-After: 12 | Espera de 12 segundos | Esperar al menos 12 segundos si queda plazo |
| Retry-After: una fecha HTTP | Depende de la hora de recepción y del reloj | Calcular un intervalo no negativo y comprobar el plazo |
| Cabecera ausente o inválida | No hay demora utilizable | Aplicar la política del proveedor o espera local acotada |
| Cuota diaria agotada según el proveedor | Los reintentos breves no restauran la cuota | Detenerse hasta que vuelva a estar disponible |
Presupuesta toda la cola
Con 120 solicitudes por minuto para toda la cuenta, 600 requieren al menos cinco minutos sin otro tráfico. Enviarlas en diez segundos y descansar después sigue siendo una ráfaga.
Un objetivo de 90 por minuto equivale a 1.5 por segundo, aproximadamente una cada 667 milisegundos. Las 600 necesitan 400 segundos, sin contar latencia ni reintentos. Con respuestas de 2 segundos, 1.5 × 2 = 3 solicitudes activas de media. Un semáforo limita las activas; un regulador compartido limita los inicios. Los reintentos también consumen cuota.
Example workload assumptions:
Account allowance: 120 requests/minute
Operating target: 90 requests/minute = 1.5 requests/second
600 requests / 1.5 requests/second = 400 seconds
Average concurrency at 2 seconds/response: 1.5 × 2 = 3Aplica espera creciente con variación aleatoria
Sin demora válida, una política puede ampliar la ventana a uno, dos, cuatro y ocho segundos y elegir aleatoriamente dentro de ella. Así los trabajadores no despiertan juntos.
La función calcula una demora, no implementa un cliente completo. El llamador debe imponer plazo total, límite de intentos, cancelación y seguridad de repetición. En el navegador, CORS puede exigir que el servidor exponga Retry-After.
function retryDelayMs(retryAfter, attempt, nowMs = Date.now()) {
const text = String(retryAfter ?? "").trim();
if (/^\d+$/.test(text)) {
const milliseconds = Number(text) * 1000;
return Number.isSafeInteger(milliseconds) ? milliseconds : Infinity;
}
if (/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/.test(text)) {
const dateMs = Date.parse(text);
if (Number.isFinite(dateMs)) return Math.max(0, dateMs - nowMs);
}
const windowMs = Math.min(8000, 1000 * 2 ** attempt);
return Math.floor(Math.random() * windowMs);
}
// Example policy: at most 4 retries and a 30-second total deadline.
// If the required wait exceeds the remaining deadline, stop.Evita repetir efectos secundarios
Consultar datos no equivale a crear un pago. Comprueba la idempotencia y si el primer intento pudo producir efectos. Reutiliza la misma clave para la misma operación lógica; una nueva en cada intento puede crear duplicados.
Un SDK puede reintentar por su cuenta. Una capa exterior multiplica el tráfico: limita los intentos de red entre todas las capas. En una acción interactiva, ofrece reintentar después en lugar de una espera infinita.
- Fija un plazo total y cancela lo pendiente.
- Comparte los límites de concurrencia y ritmo.
- Libera los recursos de la respuesta antes de esperar.
- Detente ante cuota agotada o fallo permanente.
- Registra intentos y resultado final.
Comprueba con un lote controlado
Empieza con veinte lecturas y cuenta solicitudes iniciales, reintentos, éxitos y fallos finales. Comprueba separación y concurrencia. Simula respuestas 429 y Retry-After sin cargar un servicio real.
Usa los cálculos de solicitudes por segundo y concurrencia para planificar, y contrástalos con el contrato. Si persiste el límite, busca otros consumidores y el tipo de cuota antes de aumentar ciegamente la espera.
Preguntas frecuentes
¿Un 429 significa que mi IP está bloqueada?
No necesariamente. Puede limitarse la cuenta, el token, la ruta, la IP o el servicio. Consulta la respuesta y la política del proveedor.
¿Debo reintentar inmediatamente si falta Retry-After?
No. Su ausencia no autoriza un reintento inmediato. Sigue la política del proveedor o una espera creciente acotada y aleatoria, con un presupuesto compartido.
¿Más trabajadores resuelven el error?
Pueden aumentar la presión sobre la misma cuota. Identifica qué se limita y coordina cola y concurrencia; añade capacidad solo si el contrato lo permite.
Fuentes y definiciones
Método comprobado: