Estoy haciendo múltiples llamadas a la API usando el nodo HTTP Request, pero después de un tiempo empiezo a recibir errores 429 Too Many Requests. ¿Cuál es la mejor manera de manejar los límites de velocidad de la API.
Hola @Victory1, mientras esperas una respuesta, aquí hay algunas cosas que podrían ayudarte:
Recursos sugeridos
Coincidencia automática con tu pregunta.
Documentación:
Foro:
@Yo_its_prakash, @MutedJam, @Niffzy - ustedes han ayudado con problemas similares antes, ¿pueden echar un vistazo?
Sugerido automáticamente por el bot comunitario de n8n. Es un piloto - comparte tu opinión aquí.
Pacea tus solicitudes para evitar sobrecargar el endpoint de la API.
Agrega un tiempo de espera suficiente
Un error 429 significa que has superado el límite de solicitudes de la API.
Intenta agregar un nodo Wait entre solicitudes, procesa elementos en lotes usando Loop Over Items (Batching), o implementa lógica de reintentos con backoff exponencial.
También vale la pena verificar la documentación de la API para conocer las directrices de límite de velocidad y evitar fallos innecesarios.
Hola @Victory1
Una distinción pequeña pero importante además de lo anterior — el nodo HTTP Request tiene su propia opción de Batching, que es algo diferente del batching de Loop Over Items y no requiere nodos adicionales:
1. HTTP Request → Options → Add Option → Batching
Items per Batch 1, Batch Interval 1000 = una solicitud/segundo. Sin Loop Over Items, sin nodo Wait, sin recableado.
2. Dos detalles importantes que debes conocer
- Dentro de un lote, las solicitudes se disparan en paralelo — Items per Batch
10son 10 conexiones simultáneas, no 10 espaciadas. Mantenlo en 1 si la API limita la concurrencia. - El Retry On Fail integrado de n8n es de intervalo fijo e ignora
Retry-After— así que no es exponential backoff. Para un backoff real necesitas un bucle IF + Wait que lea el encabezado tú mismo.
3. Averigua cuál es el límite que estás alcanzando primero
Registra x-ratelimit-limit / -remaining / -reset de una respuesta exitosa:
- ráfaga por segundo → el espaciado lo arregla
- cuota diaria → el espaciado no, necesitas menos llamadas
- límite de concurrencia → solo Items per Batch 1 lo arregla
El mismo 429, tres problemas diferentes.
4. Si el flujo de trabajo se ejecuta muchas veces en paralelo
El espaciado dentro de una ejecución no ayudará — cada ejecución espera cortésmente y aún así inundan la API juntas. Auto-hospedado: N8N_CONCURRENCY_PRODUCTION_LIMIT=1.
¿Cuál es la API? Feliz de ser más específico.
Hola @Victory1
Si la API tiene un endpoint de bulk o batch, el conteo de solicitudes en sí puede disminuir. Coloca un nodo Aggregate antes del nodo HTTP Request con Aggregate establecido en All Item Data, y todo el conjunto llega como un elemento bajo data. Referencialo en el cuerpo JSON:
{{ JSON.stringify($json.data) }}
Cincuenta elementos entonces salen como una solicitud en lugar de cincuenta.
Buen desglose de @Hammad_gaming. Completando la parte que señaló pero no construyó, más una categoría de 429 que ninguno de los arreglos anteriores soluciona.
El bucle Retry-After, ya que se mencionó pero no se mostró
Nodo HTTP Request: desactiva Retry On Fail y establece Options >
Response > Never Error = true. Necesitas que el 429 vuelva como
datos, no como un error lanzado, o no podrás leer el encabezado.
Luego IF en {{ $json.statusCode }} es igual a 429 → Nodo Code para
calcular la espera → Nodo Wait → vuelve al nodo HTTP.
Nodo Code:
const h = $json.headers || {};
let sec = 1;
if (h[‘retry-after’]) {
const v = h[‘retry-after’];
// Retry-After es delta-segundos o una fecha HTTP
sec = isNaN(v) ? Math.max(0, (new Date(v) - Date.now()) / 1000)
: Number(v);
} else if (h[‘x-ratelimit-reset’]) {
const r = Number(h[‘x-ratelimit-reset’]);
// algunas APIs envían segundos epoch, otras envían segundos restantes
sec = r > 1e9 ? r - Math.floor(Date.now() / 1000) : r;
} else {
const n = $runIndex || 0;
sec = Math.min(2 ** n, 60);
}
// jitter — esta línea importa más de lo que parece
sec = sec * (0.5 + Math.random() * 0.5);
return [{ json: { waitSeconds: Math.ceil(sec) } }];
Tres cosas que es fácil pasar por alto:
Retry-After puede ser una fecha HTTP, no solo un número de
segundos. Analizarlo como entero silenciosamente te da NaN y una
espera de cero segundos, así que reintentas al instante y obtienes
429 de nuevo.
x-ratelimit-reset es inconsistente entre APIs — GitHub envía
segundos epoch, otros envían segundos restantes. La verificación de
magnitud maneja ambos.
La línea jitter es la que la gente omite. Sin ella, si tienes 20
elementos que todos golpean 429 en el mismo momento, todos esperan
exactamente la misma duración y todos reintentan en el mismo
instante. Has reconstruido el problema original con un paso extra.
Aleatorizar la espera los dispersa.
La tormenta de reintentos, que el espaciado no soluciona
Vale la pena ser explícito: Retry On Fail reintenta por elemento.
Cincuenta elementos, tres intentos cada uno, y un 429 que golpea en
el elemento 20 significa que puedes disparar 90 solicitudes extra a
una API que te acaba de decir que pares. Algunas APIs responden a
eso extendiendo el bloqueo.
Si usas Retry On Fail en un lote, establece Max Tries en 2 y maneja
los reintentos reales con el bucle anterior, donde el espaciado está
bajo tu control.
El que nadie ha mencionado: límites de tokens, no límites de solicitudes
@Victory1 — si esto es OpenAI, Anthropic, Cohere o cualquier API de
LLM, es probable que no estés golpeando un límite de solicitudes en
absoluto.
Esos proveedores aplican dos límites separados: solicitudes por
minuto y tokens por minuto. TPM es generalmente el que golpeas
primero, y ninguno de los consejos de espaciado anterior lo toca,
porque la restricción es el tamaño de la carga útil en lugar de la
frecuencia de llamadas.
Síntoma que te dice cuál: si los 429 empeoran cuando tus documentos
de entrada se hacen más largos, pero el número de llamadas no ha
cambiado, es TPM.
Los arreglos también son diferentes — reduces tokens en lugar de
desacelerar. Recorta el prompt, suelta max_tokens si lo has
establecido alto (algunos proveedores cuentan la reserva contra tu
presupuesto, no la salida real), divide documentos largos, o
dirige llamadas cortas a un modelo más pequeño.
Los encabezados de respuesta lo nombran directamente si los
registras:
x-ratelimit-remaining-requests vs x-ratelimit-remaining-tokens.
Lo que llega a cero primero es tu límite real.
Y uno que desperdicia una tarde
Algunas APIs no devuelven 429 en absoluto. El endpoint GraphQL de
Shopify devuelve 200 con un estado de aceleración dentro del cuerpo.
También lo hace más de un proveedor de pagos.
Si tu flujo de trabajo “no está dando error” pero los datos se
pierden silenciosamente, verifica el cuerpo de respuesta en lugar
del código de estado. Un IF en statusCode nunca lo atrapará.
¿Cuál es la API? El arreglo correcto es diferente para los tres casos.