Límite de tasa Cómo evitar recibir el código 429 en todas las APIs que uses
HTTP 429 Demasiadas solicitudes — cómo leer los encabezados Retry-After, implementar retroceso exponencial con jitter, entender los algoritmos de tanque de tokens vs. tanque de fuga y implementar limitación de velocidad en su propia API.
Has alcanzado 429. Tu script ha estado golpeando la API durante la última hora, tus registros están llenos de rojos y la implementación está a 20 minutos. Ese es el momento en que deja de ser abstracto.
El código HTTP 429 Too Many Requests significa que has enviado más solicitudes de las que el servidor permite en un intervalo de tiempo dado. Leer correctamente la respuesta y reintentar de forma adecuada es una habilidad que la mayoría de los desarrolladores solo adquieren tras haberse equivocado. Aquí está la imagen completa.
Lo que realmente dice el 429
El código de estado solo es la mitad del mensaje. La información real está en los encabezados:
Retry-After: 30— espera 30 segundos antes de reintentar. También puede ser una fecha HTTP:Retry-After: Mon, 08 Jun 2026 15:00:00 GMTX-RateLimit-Limit: 100— número total de solicitudes permitidas en el intervaloX-RateLimit-Remaining: 0— número de solicitudes restantes en el intervalo actual (estás en cero)X-RateLimit-Reset: 1749391200— marca del tiempo Unix cuando se reinicia el intervalo
No todas las APIs envían todos estos datos. GitHub envía el conjunto completo. Stripe envía Retry-After. Algunas APIs REST no envían nada y esperan que lo adivines. Si tienes Retry-After, úsalo exactamente — es lo que el servidor te dice sobre el tiempo mínimo seguro de espera. Si no lo haces, el backoff exponencial será tu opción de respaldo.
La forma incorrecta de reintentar
La implementación ingenua se ve así:
async function fetchWithoutBackoff(url) {
while (true) {
const res = await fetch(url);
if (res.ok) return res;
if (res.status === 429) continue; // immediately retry
}
}
Esto es activamente dañino. Si 10 instancias de tu servicio tocan 429 al mismo tiempo y todos reintentan inmediatamente, cada reintentar llega al mismo tiempo — el problema del rebaño que ruge. Vuelves a ser rate-limited de inmediato, en un bucle estrecho que puede durar indefinidamente y hace que tu cliente parezca que está abusando intencionalmente de la API.
Backoff exponencial con jitter
El patrón correcto: cada reintentar espera más tiempo que el anterior (exponencial), y un desplazamiento aleatorio evita que los reintentos se sincronicen entre múltiples clientes (jitter).
async function fetchWithBackoff(url, options = {}, maxRetries = 5) {
let attempt = 0;
while (attempt <= maxRetries) {
const res = await fetch(url, options);
if (res.ok) return res;
if (res.status !== 429) {
throw new Error(`Request failed: ${res.status}`);
}
if (attempt === maxRetries) {
throw new Error(`Rate limited after ${maxRetries} retries`);
}
// Use Retry-After if provided; otherwise exponential backoff + jitter
const retryAfter = res.headers.get('Retry-After');
let waitMs;
if (retryAfter) {
const seconds = isNaN(retryAfter)
? (new Date(retryAfter) - Date.now()) / 1000 // HTTP date
: Number(retryAfter); // seconds
waitMs = seconds * 1000;
} else {
const baseDelay = 1000 * Math.pow(2, attempt); // 1s, 2s, 4s, 8s, 16s
const jitter = Math.random() * 1000; // 0–1000ms random offset
waitMs = baseDelay + jitter;
}
console.log(`Rate limited. Waiting ${Math.round(waitMs / 1000)}s (attempt ${attempt + 1}/${maxRetries})`);
await new Promise(resolve => setTimeout(resolve, waitMs));
attempt++;
}
}
La línea de jitter es la parte que más implementaciones omiten. Sin ella, los reintentos de múltiples procesos paralelos aún llegan en grupos. Con ella, se distribuyen por todo el intervalo de espera.
Para APIs que devuelven Retry-After, úsalo como el floor — si aún estás recibiendo 429 después del tiempo especificado de espera, aplica backoff exponencial encima.
Bandeja de tokens vs bandeja de drenaje
Dos algoritmos dominan las implementaciones de limitadores de velocidad. Comprender cuál estás tratando dice mucho sobre cómo se comportará la API bajo presión — y cuál algoritmo elegir cuando estés construyendo el tuyo propio.
Bandeja de tokens
La bandeja contiene hasta N tokens. Cada solicitud cuesta 1 token. Los tokens se reemplenan a una tasa fija (por ejemplo, 10 por segundo). Si la bandeja está vacía, la solicitud es rechazada o colgada.
Amigable con picos. Si no has hecho solicitudes en mucho tiempo, has acumulado tokens y puedes disparar un pico sin tocar el límite. El API de GitHub funciona así — 5.000 solicitudes por hora, pero puedes usarlas de forma simultánea si no has tocado la API en horas. Ideal para casos interactivos donde el tráfico es espeso.
Bandeja de drenaje
Las solicitudes entran en una cola y se vacían a una tasa fija, independientemente de la velocidad con que llegan. Si la cola se llena, las solicitudes entrantes son descartadas.
Salida suave, sin picos. Aunque aún tengas cuota disponible, las solicitudes salen lentamente a la tasa configurada. El módulo de Nginx limit_req usa esto. Mejor para proteger sistemas subyacentes de picos — útil para la entrega de webhooks, llamadas a APIs externas y cualquier caso donde la capacidad de flujo predecible sea más importante que la tolerancia a picos.
¿Qué elegir cuando se implementa uno propio: Puntos de acceso para usuarios que necesiten tolerancia a picos → bandeja de tokens. Entregas de webhooks o llamadas a APIs externas → bandeja de drenaje. Tareas de fondo donde la salida suave sea importante → bandeja de drenaje.
Cálculo de tasas seguras de solicitudes
Antes de escribir cualquier lógica de reintentos, averigua qué realmente puedes hacer. Si una API dice "1.000 solicitudes por hora", eso es 16,67 solicitudes por minuto o 0,278 por segundo. Añade un margen de seguridad de 20% y estarás en unos 13 solicitudes por minuto — suficiente margen para evitar problemas de timing en casos extremos donde dos ventanas se superponen.
Utiliza el Calculadora de Límite de Velocidad para convertir números de cuota en tasas por segundo y por minuto, encontrar el intervalo adecuado entre solicitudes y ver cómo tu nivel de concurrencia afecta el riesgo de picos.
Implementación de límite de velocidad en tu propia API
Si estás en el otro lado y quieres añadir un comportamiento adecuado de 429 a tu propia API:
- Elige la gravedad adecuada. Por IP es fácil, pero falla para servicios detrás de NAT o con egress compartido. Por clave de API es mejor, pero requiere autenticación. Por ID de usuario es ideal si la tienes. No mezcles gravedades sin saber cuál gana.
- Siempre devuelve
Retry-After. Un 429 sinRetry-Afterobliga a cada cliente a implementar su propia heurística de backoff. Obtendrás más rebaño que ruge, no menos. - Usa Redis para el límite de velocidad distribuido. Los contadores en memoria no funcionan entre múltiples instancias de servidor. Redis
INCR+EXPIREes el patrón estándar. Las bibliotecas como rate-limiter-flexible (Node) y slowapi (Python/FastAPI) lo abstrae correctamente. - Registra cada 429 que emites. Un aumento en 429s desde una sola clave indica ya sea un error del cliente o un uso intencionalmente abusivo. Ambos son importantes de conocer en tiempo real.
- No limite la velocidad en el fallo de autenticación. Devuelve 401 para credenciales incorrectas, no 429. Limitar la velocidad en fallos de autenticación es cómo accidentalmente bloqueas a tus propios usuarios durante una rotación de credenciales.
Lo que debes hacer ahora mismo
Si estás recibiendo 429s:
- Verificar
Retry-Afterprimero — úsalo si está disponible, no inventes tu propio retraso - Implementa backoff exponencial con jitter — el código anterior es listo para copiar y pegar
- Registra el
X-RateLimit-Remainingencabezado en cada respuesta — podrías estar consumiendo cuota más rápido de lo que crees - Almacena respuestas donde los datos no cambian frecuentemente
Si estás implementando límites de velocidad: elige una biblioteca basada en Redis, devuelve Retry-After en cada 429, monitorea la tasa de 429 por clave y no limite la velocidad en el fallo de autenticación.
El 429 no es el enemigo — es la API que te dice exactamente qué pasó mal y (normalmente) cuánto tiempo debes esperar. La mayoría de los problemas de límite de velocidad se deben a ignorar ese mensaje y reintentar inmediatamente. No hagas eso.
Instalar extensiones
Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas
恵 ¡El marcador ha llegado!
Marcador es una forma divertida de llevar un registro de tus juegos, todos los datos se almacenan en tu navegador. ¡Próximamente habrá más funciones!
Herramientas clave
Ver todo Los recién llegados
Ver todoActualizar: Nuestro última herramienta was added on Jun 23, 2026
