Gerenciando o erro 429 Too Many Requests: exponential backoff e retry no cliente
Seu app recebe 429 e responde tentando de novo imediatamente — piorando tudo. Veja como implementar exponential backoff com jitter e dar um feedback decente ao usuário.
Por Equipe We Codex3 min de leitura
O servidor respondeu 429 Too Many Requests. A reação instintiva do código é tentar de novo. A reação errada é tentar de novo *imediatamente* — e milhares de clientes fazendo isso ao mesmo tempo transformam um soluço em queda.
Por que o 429 existe
Ele vem do rate limiting da API (explicado em Rate limiting em Node.js: como proteger suas APIs contra sobrecarga e abusos sem afetar a UX). É o servidor dizendo: "estou protegendo o sistema; volte daqui a pouco". Respeitar esse pedido é o que mantém a experiência boa para todos.
Exponential backoff com jitter
A ideia é simples: a cada falha, espere mais antes de tentar de novo — 1s, 2s, 4s, 8s — e adicione um valor aleatório para que os clientes não voltem todos no mesmo instante.
async function comRetry<T>(fn: () => Promise<Response>, tentativas = 4): Promise<Response> {
for (let i = 0; i < tentativas; i++) {
const res = await fn()
if (res.status !== 429 && res.status < 500) return res
const retryAfter = Number(res.headers.get('Retry-After'))
const base = retryAfter > 0 ? retryAfter * 1000 : 2 ** i * 1000
await new Promise((r) => setTimeout(r, base + Math.random() * 500))
}
throw new Error('Serviço indisponível. Tente novamente em instantes.')
}Se o servidor mandou Retry-After, ele manda. Senão, o backoff decide.
Nem tudo deve ser repetido
- Leituras (GET) podem ser repetidas com segurança.
- Escritas (pagamento, pedido) só com idempotência garantida no backend — senão você cria pedidos duplicados. Veja Idempotência: como evitar cobrança duplicada e pedidos repetidos.
- Erros 4xx como 400 e 422 nunca devem ser repetidos: o problema está no dado enviado.
A parte que o usuário vê
Retentativa silenciosa resolve picos curtos. Quando o bloqueio é maior, a interface precisa avisar: mensagem humana ("Muitas tentativas. Tente de novo em 30 segundos"), botão desabilitado com contagem regressiva e nenhuma perda do que a pessoa digitou. No app, o cuidado é o mesmo — detalhes em Erro 429 no app: como avisar o usuário e tentar de novo sem travar.
Combine com debounce
Muitos 429 nascem no próprio front: uma busca disparando requisição a cada tecla. Debounce resolve antes do problema existir (Debounce e throttle em inputs: busca rápida sem derrubar a API).
Esse tipo de resiliência vem de fábrica nos sistemas web e apps que desenvolvemos. Quer revisar o seu?
- Erro 429
- Retry
- Exponential Backoff
- Frontend
Resolver de vez, com quem faz isso todo dia
Quer saber quão exposto está o seu sistema hoje?
Este artigo mostra o caminho. A implementação sob medida — o detalhe que muda o resultado no seu caso — é o trabalho da We Codex, empresa de engenharia do grupo Wocom.
Continue lendo
Tudo sobre Segurança- Ler artigo
Segurança3 min
Rate limiting em Node.js: como proteger suas APIs contra sobrecarga e abusos sem afetar a UX
Sem limite de requisições, um script mal-intencionado (ou um bug no seu próprio app) derruba a API. Veja como aplicar rate limit no Node.js sem bloquear clientes legítimos.
- Ler artigo
Web & Performance3 min
Debounce e throttle em inputs: busca rápida sem derrubar a API
A busca dispara uma requisição a cada letra digitada e a API sofre. Debounce e throttle resolvem — e deixam a interface mais fluida.
- Ler artigo
Mobile3 min
Erro 429 no app: como avisar o usuário e tentar de novo sem travar
O app recebe 429 e mostra "erro desconhecido" — ou tenta de novo sem parar. Como tratar limites de requisição no React Native com feedback claro.