Web y desarrollo / CLEARBYTE

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.

Decisiones ante distintas respuestas
ObservaciónSignificadoAcción
Retry-After: 12Espera de 12 segundosEsperar al menos 12 segundos si queda plazo
Retry-After: una fecha HTTPDepende de la hora de recepción y del relojCalcular un intervalo no negativo y comprobar el plazo
Cabecera ausente o inválidaNo hay demora utilizableAplicar la política del proveedor o espera local acotada
Cuota diaria agotada según el proveedorLos reintentos breves no restauran la cuotaDetenerse 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 = 3

Aplica 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: