Estou fazendo múltiplas chamadas de API usando o nó HTTP Request, mas depois de um tempo começar a receber erros 429 Too Many Requests. Qual é a melhor maneira de lidar com limites de taxa de API.
Oi @Victory1, enquanto você aguarda uma resposta, aqui estão algumas coisas que podem ajudar:
Recursos sugeridos
Automaticamente correspondido à sua pergunta.
Docs:
Fórum:
@Yo_its_prakash, @MutedJam, @Niffzy - vocês já ajudaram com problemas semelhantes antes, podem dar uma olhada?
Automaticamente sugerido pelo bot da comunidade do n8n. É um piloto - compartilhe seu feedback aqui.
Regule suas solicitações para evitar sobrecarregar o endpoint da API.
Adicione tempo de espera suficiente
Um erro 429 significa que você excedeu o limite de requisições da API.
Tente adicionar um nó Wait entre as requisições, processar itens em lotes usando Loop Over Items (Batching), ou implementar lógica de retry com backoff exponencial.
Também vale a pena verificar a documentação da API para orientações sobre limites de taxa e evitar falhas desnecessárias.
Oi @Victory1
Pequena mas importante distinção sobre o acima — o nó HTTP Request tem sua própria opção de Batching, que é uma coisa diferente do batching Loop Over Items e não precisa de nós extras:
1. HTTP Request → Options → Add Option → Batching
Items per Batch 1, Batch Interval 1000 = uma requisição/segundo. Sem Loop Over Items, sem nó Wait, sem reconfiguração.
2. Duas armadilhas que vale a pena conhecer
- Dentro de um batch, as requisições disparam em paralelo — Items per Batch
10são 10 conexões simultâneas, não 10 espaçadas. Mantenha em 1 se a API limita concorrência. - O Retry On Fail integrado do n8n é de intervalo fixo e ignora
Retry-After— então não é backoff exponencial. Para backoff real você precisa de um loop IF + Wait lendo o header você mesmo.
3. Descubra qual limite você está atingindo primeiro
Registre x-ratelimit-limit / -remaining / -reset de uma resposta bem-sucedida:
- burst por segundo → pacing resolve
- quota diária → pacing não resolve, você precisa de menos chamadas
- limite de concorrência → apenas Items per Batch 1 resolve
Mesmo 429, três problemas diferentes.
4. Se o workflow roda muitas vezes em paralelo
Pacing dentro de uma execução não vai ajudar — cada execução espera educadamente e mesmo assim inundam a API juntas. Self-hosted: N8N_CONCURRENCY_PRODUCTION_LIMIT=1.
Qual é a API? Fico feliz em ser mais específico.
Oi @Victory1
Se a API tem um endpoint em lote ou batch, a contagem de requisições pode diminuir. Coloque um nó Aggregate antes do nó HTTP Request com Aggregate definido como All Item Data, e todo o conjunto chega como um item sob data. Faça referência a ele no corpo JSON:
{{ JSON.stringify($json.data) }}
Cinquenta itens saem como uma única requisição em vez de cinquenta.
Ótima análise do @Hammad_gaming. Preenchendo a parte que ele apontou mas não construiu, além de uma categoria de 429 que nenhuma das soluções acima resolve.
O loop de Retry-After, já que foi mencionado mas não mostrado
Nó HTTP Request: desative Retry On Fail e defina Options >
Response > Never Error = true. Você precisa que o 429 retorne como
dados, não como um erro lançado, ou não conseguirá ler o header.
Depois IF em {{ $json.statusCode }} equals 429 → nó Code para
calcular a espera → nó Wait → loop de volta para o nó HTTP.
Nó Code:
const h = $json.headers || {};
let sec = 1;
if (h[‘retry-after’]) {
const v = h[‘retry-after’];
// Retry-After é delta-seconds ou uma HTTP-date
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’]);
// algumas APIs enviam epoch seconds, outras enviam seconds-remaining
sec = r > 1e9 ? r - Math.floor(Date.now() / 1000) : r;
} else {
const n = $runIndex || 0;
sec = Math.min(2 ** n, 60);
}
// jitter — essa linha importa mais do que parece
sec = sec * (0.5 + Math.random() * 0.5);
return [{ json: { waitSeconds: Math.ceil(sec) } }];
Três coisas ali que são fáceis de perder:
Retry-After pode ser uma HTTP-date, não apenas um número de
segundos. Fazer parse dele como inteiro silenciosamente gera NaN e
uma espera de zero segundos, então você retenta instantaneamente e
recebe 429 novamente.
x-ratelimit-reset é inconsistente entre APIs — GitHub envia epoch
seconds, outras enviam seconds-remaining. A verificação de magnitude
lidam com ambas.
A linha de jitter é aquela que as pessoas pulam. Sem ela, se você
tem 20 itens que todos batem em 429 no mesmo momento, todos esperam
exatamente a mesma duração e todos retentam no mesmo instante. Você
reconstruiu o problema original com um passo extra. Randomizar a
espera os distribui.
A tempestade de retry, que pacing não resolve
Vale ser explícito: Retry On Fail retenta por item. Cinquenta
itens, três tentativas cada uma, e um 429 que atinge no item 20
significa que você pode disparar 90 requisições extras em uma API
que acabou de lhe dizer para parar. Algumas APIs respondem
estendendo o bloqueio.
Se estiver usando Retry On Fail em um lote, defina Max Tries para
2 e lide com as tentativas reais com o loop acima, onde o pacing
está sob seu controle.
Aquele que ninguém mencionou: token limits, não request limits
@Victory1 — se for OpenAI, Anthropic, Cohere ou qualquer API LLM,
há uma boa chance de você não estar batendo em um limite de
requisição em tudo.
Esses provedores impõem dois limites separados: requisições por
minuto e tokens por minuto. TPM geralmente é o que você atinge
primeiro, e nenhuma das dicas de pacing acima o toca, porque a
constrição é o tamanho da carga útil, não a frequência de chamadas.
Sintoma que te diz qual: se os 429s pioram quando seus documentos
de entrada ficam mais longos, mas o número de chamadas não mudou,
é TPM.
As correções são diferentes também — você reduz tokens em vez de
desacelerar. Aparque o prompt, remova max_tokens se tiver definido
alto (alguns provedores contam a reserva contra seu orçamento, não a
saída real), divida documentos longos, ou roteie chamadas curtas
para um modelo menor.
Os response headers nomeiam diretamente se você registrá-los:
x-ratelimit-remaining-requests vs x-ratelimit-remaining-tokens.
Qual quer que atinja zero primeiro é seu limite real.
E aquele que desperdiça uma tarde
Algumas APIs não retornam 429 em tudo. O endpoint GraphQL do
Shopify retorna 200 com um status de throttle dentro do corpo.
Igual faz mais de um provedor de pagamento.
Se seu workflow “não está errando” mas dados estão desaparecendo
silenciosamente, verifique o corpo da resposta em vez do código de
status. Um IF em statusCode nunca vai pegar isso.
Qual é a API? A correção certa é diferente para todos os três
casos.