Como Resolver o Erro 429 Too Many Requests
O erro 429 Too Many Requests é um código de status HTTP definido no RFC 6585 que sinaliza que um cliente excedeu o limite de taxa imposto pelo servidor ou por um proxy intermediário. O servidor recusa pedidos adicionais até que a janela de limitação de taxa seja redefinida, retornando opcionalmente um cabeçalho Retry-After indicando quanto tempo o cliente deve aguardar.
Ao contrário de um erro 503 Service Unavailable, que reflete uma falha de capacidade do lado do servidor, um 429 é uma rejeição deliberada e orientada por políticas. Compreender essa distinção é fundamental: a solução nem sempre envolve escalar a infraestrutura — trata-se de identificar *quem* está enviando demasiados pedidos, *porquê*, e depois corrigir o comportamento na camada correta da pilha.
O Que Realmente Causa um Erro 429
O erro surge em múltiplas camadas, e confundi-las leva a um diagnóstico incorreto. A causa raiz enquadra-se numa de quatro categorias:
- Limitação de taxa do lado do servidor — Servidores web (Apache, Nginx), proxies reversos (HAProxy, Varnish) ou nós de borda CDN (Cloudflare, Fastly) impõem limites de pedidos por IP ou por token.
- Throttling na camada de aplicação — Plugins WordPress, middleware personalizado ou gateways de API impõem os seus próprios limites independentemente do servidor web.
- Esgotamento de quota de API de terceiros — A sua aplicação chama uma API externa (Google Maps, Stripe, OpenAI) mais rapidamente do que a quota do fornecedor permite, e o 429 propaga-se de volta ao utilizador final.
- Tráfego automatizado malicioso ou não controlado — Tentativas de login por força bruta, scrapers agressivos, scripts de monitorização mal configurados ou crawlers mal escritos saturam os orçamentos de pedidos.
Um caso extremo frequentemente ignorado: ambientes de alojamento partilhado onde um pico de tráfego de um inquilino vizinho consome pools de ligações partilhadas, fazendo com que a sua aplicação receba respostas 429 de um balanceador de carga upstream mesmo que o seu próprio código esteja bem configurado. Se estiver num plano de Alojamento Web Partilhado e observar picos intermitentes de 429 sem um pico correspondente no seu próprio tráfego, esta é a primeira hipótese a testar.
Passo 1: Identificar a Origem dos Pedidos Excessivos
Corrigir um 429 sem identificar a sua origem é uma suposição. Comece pelos dados.
Leitura dos Logs de Acesso do Apache
grep " 429 " /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20Este comando extrai todas as respostas 429, conta as ocorrências por endereço IP e classifica-as. Um IP que aparece milhares de vezes em minutos é um bot, um script mal configurado ou um atacante.
Leitura dos Logs de Acesso do Nginx
awk '$9 == 429 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20Correlação com Caminhos de Pedidos
grep " 429 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20Se /wp-login.php ou /xmlrpc.php dominar o resultado, está a lidar com uma campanha de força bruta ou de preenchimento de credenciais. Se um endpoint de API como /api/v1/search encabeçar a lista, o culpado é provavelmente um cliente mal configurado ou um scraper.
Utilização de fail2ban para Identificar Padrões
fail2ban-client status
fail2ban-client status nginx-req-limitSe fail2ban estiver configurado com uma jail nginx-req-limit, mostrará exatamente quais os IPs que foram banidos devido a violações de limite de taxa, poupando um tempo significativo de análise de logs.
Passo 2: Configurar a Limitação de Taxa ao Nível do Servidor Web
Apache: Utilização de mod_ratelimit e mod_evasive
O snippet .htaccess frequentemente divulgado online utiliza mod_rewrite para retornar um 403, não um 429 adequado. Uma abordagem mais semanticamente correta e operacionalmente sólida utiliza mod_evasive para mitigação de DoS.
Instale e configure mod_evasive no Debian/Ubuntu:
apt install libapache2-mod-evasive
a2enmod evasiveEm seguida, adicione ao seu virtual host Apache ou configuração global:
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSEmailNotify admin@yourdomain.com
DOSLogDir /var/log/mod_evasive
</IfModule>Isto bloqueia qualquer IP que aceda à mesma página mais de 5 vezes por segundo, ou ao site inteiro mais de 50 vezes por segundo, durante um período de arrefecimento de 10 segundos.
Para uma resposta 429 adequada via .htaccess no Apache com mod_rewrite, é necessário um documento de erro personalizado:
ErrorDocument 429 "Too Many Requests"
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^.*(SemrushBot|AhrefsBot|MJ12bot|DotBot).*$ [NC]
RewriteRule .* - [R=429,L]
</IfModule>Nginx: limit_req_zone com Tratamento Adequado de Burst
O ngx_http_limit_req_module do Nginx é uma das ferramentas de limitação de taxa mais eficazes disponíveis. Os parâmetros principais que são frequentemente mal configurados são burst e nodelay.
Em /etc/nginx/nginx.conf ou num ficheiro de inclusão dedicado:
http {
# Zone keyed by client IP, 10MB shared memory, 10 requests/second baseline
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
# Return 429 instead of the default 503
limit_req_status 429;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
}
location /wp-login.php {
limit_req zone=login_limit burst=3 nodelay;
}
}
}Nuance crítica: Sem limit_req_status 429, o Nginx retorna um 503 para pedidos com limite de taxa por padrão. Defini-lo como 429 é semanticamente correto e permite que os clientes implementem lógica de backoff Retry-After adequada.
nodelay vs. sem flag:
- Sem
nodelay: os pedidos em excesso ficam em fila e são servidos com atraso adicional, consumindo ligações de worker. - Com
nodelay: os pedidos em excesso além do burst são imediatamente rejeitados com um 429, libertando recursos mais rapidamente. Utilizenodelaypara endpoints de login e APIs públicas.
Adição de um Cabeçalho Retry-After
Os clientes que respeitam o RFC 6585 honrarão um cabeçalho Retry-After. No Nginx, adicione-o à resposta de erro:
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
add_header Retry-After 60 always;
}Passo 3: Diagnosticar e Corrigir Conflitos de Plugins WordPress
O WordPress é uma fonte comum de erros 429 auto-infligidos. Plugins que consultam APIs externas em cada carregamento de página — ferramentas SEO a obter dados de palavras-chave, plugins de análise a comunicar com o servidor, ou extensões WooCommerce a consultar gateways de pagamento — podem esgotar rapidamente os limites de taxa.
Procedimento de isolamento sistemático:
- Desative todos os plugins através do painel WordPress ou, se o painel estiver inacessível, via WP-CLI:
wp plugin deactivate --all- Reative os plugins um de cada vez, testando após cada ativação:
wp plugin activate plugin-slug- Monitorize o log de acesso num terminal separado enquanto reativa:
tail -f /var/log/nginx/access.log | grep " 429 "- Assim que o plugin problemático for identificado, verifique as suas definições para intervalos de consulta de API ou opções de frequência de pedidos antes de o desativar permanentemente.
Infratores comuns: Jetpack (módulos de estatísticas e sincronização), Yoast SEO (quando ligado ao MyYoast), WooCommerce Subscriptions, e qualquer plugin que utilize o wp_remote_get() integrado do WordPress num loop sem cache de transientes.
A correção correta quase nunca é remover o plugin — é garantir que as respostas da API são armazenadas em cache utilizando transientes do WordPress:
$cached = get_transient( 'my_api_response' );
if ( false === $cached ) {
$response = wp_remote_get( 'https://api.example.com/data' );
set_transient( 'my_api_response', $response, HOUR_IN_SECONDS );
$cached = $response;
}Passo 4: Implementar Throttling de Pedidos de API no Código da Aplicação
Quando a sua aplicação é o *cliente* que acede a uma API de terceiros, é responsável por respeitar os seus limites de taxa. Depender de capturar respostas 429 de forma reativa é má engenharia — implemente throttling proativo.
Node.js com p-throttle
import pThrottle from 'p-throttle';
const throttle = pThrottle({
limit: 10, // max 10 calls
interval: 1000 // per 1000ms (1 second)
});
const throttledFetch = throttle(async (url) => {
const response = await fetch(url);
return response.json();
});Python com tenacity para Backoff Exponencial
O throttling por si só é insuficiente se a API impuser limites de burst. Combine throttling com backoff exponencial em respostas 429:
import requests
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception
def is_rate_limited(exception):
return (
isinstance(exception, requests.HTTPError)
and exception.response.status_code == 429
)
@retry(
retry=retry_if_exception(is_rate_limited),
wait=wait_exponential(multiplier=1, min=2, max=60),
stop=stop_after_attempt(5)
)
def call_api(url):
response = requests.get(url)
response.raise_for_status()
return response.json()Isto tenta novamente até 5 vezes com backoff exponencial (2s, 4s, 8s, 16s, 32s), limitado a 60 segundos — um padrão que respeita a infraestrutura do fornecedor de API enquanto recupera de forma elegante.
Respeitar o Cabeçalho Retry-After
Se a API retornar um cabeçalho Retry-After, utilize-o em vez de um backoff fixo:
def call_with_retry_after(url):
response = requests.get(url)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 5))
time.sleep(retry_after)
return call_with_retry_after(url)
response.raise_for_status()
return response.json()Passo 5: Bloquear e Gerir Bots em Múltiplas Camadas
Os bots raramente se anunciam honestamente, mas deixam impressões digitais em strings de user-agent, padrões de pedidos e anomalias de cabeçalho.
Bloquear Bots Maliciosos Conhecidos no Nginx
map $http_user_agent $bad_bot {
default 0;
~*SemrushBot 1;
~*AhrefsBot 1;
~*MJ12bot 1;
~*DotBot 1;
~*PetalBot 1;
~*serpstatbot 1;
}
server {
if ($bad_bot) {
return 429;
}
}Gerir a Taxa de Crawl via robots.txt
User-agent: Googlebot
Crawl-delay: 2
User-agent: *
Crawl-delay: 10Note que Crawl-delay não é respeitado por todos os crawlers, mas sinaliza a intenção e é respeitado pelo Bing, Yandex e pela maioria dos bots bem comportados.
Integração com Web Application Firewall (WAF)
Um WAF a operar na borda CDN (Cloudflare, AWS WAF, Sucuri) pode impor limites de taxa antes que o tráfego chegue ao seu servidor de origem, reduzindo drasticamente a carga. As regras de Rate Limiting do Cloudflare, por exemplo, podem ser configuradas para desafiar ou bloquear IPs que excedam um limiar sem quaisquer alterações à configuração do seu servidor de origem — uma vantagem operacional significativa para sites de alto tráfego.
Passo 6: Ajustar as Definições de Plugins de Segurança no WordPress
Se utilizar o Wordfence, os limiares de limitação de taxa são frequentemente definidos de forma conservadora e podem desencadear falsos positivos para utilizadores legítimos, particularmente em sites com uso intenso de AJAX ou atividade de utilizadores com sessão iniciada.
Navegue até Wordfence > Firewall > All Firewall Options > Rate Limiting e reveja:
- How should we treat Google’s crawlers — defina como “Verified Google crawlers are not rate limited” para evitar impacto no SEO.
- If anyone’s requests exceed — aumente o limiar do valor padrão (por exemplo, de 240 para 480 pedidos por minuto para utilizadores com sessão iniciada em sites com muito conteúdo).
- If a crawler’s page views exceed — ajuste com base nos seus requisitos reais de orçamento de crawl.
Após o ajuste, monitorize a vista de Tráfego em Direto do Wordfence durante 24–48 horas para confirmar que os utilizadores legítimos já não estão a ser bloqueados.
Passo 7: Limpar a Cache do Lado do Cliente e Diagnosticar Problemas ao Nível do Browser
Uma resposta 429 em cache no browser é rara, mas possível se a resposta incluir cabeçalhos Cache-Control: max-age (uma configuração incorreta do servidor). As respostas 429 padrão não devem ser armazenadas em cache.
Chrome:
Settings > Privacy and Security > Clear browsing dataSelecione Cached images and files e Cookies and other site data, depois limpe.
Verifique os cabeçalhos de resposta diretamente utilizando curl para excluir comportamento específico do browser:
curl -I -X GET https://yourdomain.com/problematic-endpointProcure os cabeçalhos Cache-Control, Retry-After e X-RateLimit-* na resposta. Estes cabeçalhos revelam exatamente qual camada está a impor o limite e quando o cliente pode tentar novamente.
Comparação: Abordagens de Limitação de Taxa por Camada
| Camada | Ferramenta / Método | Granularidade | Overhead | Melhor Para |
|---|
| — | — | — | — | — |
|---|
| CDN / Edge | Cloudflare Rate Limiting, AWS WAF | Por IP, por caminho, por cabeçalho | Muito baixo (pré-origem) | DDoS, mitigação de scrapers |
|---|
| Proxy Reverso | Nginx `limit_req_zone` | Por IP, por zona | Baixo | Endpoints de API, páginas de login |
|---|
| Servidor Web | Apache `mod_evasive` | Por IP, por página | Baixo-médio | Alojamento partilhado, stacks legados |
|---|
| Aplicação | Throttle de middleware, gateway de API | Por utilizador, por token, por chave | Médio | SaaS multi-inquilino, REST APIs |
|---|
| Plugin CMS | Wordfence, iThemes Security | Por IP, por função de utilizador | Médio-alto | Proteção específica para WordPress |
|---|
| Código do Cliente | `tenacity`, `p-throttle`, backoff | Por pedido de saída | Do lado da aplicação | Consumo de API de terceiros |
|---|
Quando Contactar o Seu Fornecedor de Alojamento
Escale para o seu fornecedor de alojamento quando:
- O 429 origina de um balanceador de carga upstream ou proxy reverso que não controla.
- A análise de logs mostra que a sua aplicação está bem dentro dos volumes de pedidos esperados, mas o erro persiste.
- Necessita de uma isenção temporária de limite de taxa durante um pico de tráfego planeado (lançamento de produto, campanha de marketing).
- O erro aparece apenas em regiões geográficas específicas, sugerindo problemas de CDN ou de roteamento anycast.
Ao utilizar um plano de VPS Hosting, tem acesso direto aos ficheiros de configuração do servidor e pode implementar todas as alterações Nginx e Apache descritas acima sem abrir um ticket de suporte. Em infraestrutura gerida como Servidores Dedicados, a equipa de suporte do seu fornecedor pode ajudar com rastreamento de ligações ao nível do kernel e regras de firewall de hardware que vão além do que a configuração na camada de aplicação pode alcançar.
Se a sua pilha inclui um painel de controlo, o VPS com cPanel expõe as definições de ModSecurity e limitação de taxa do Apache através de uma GUI, o que simplifica a configuração para equipas sem profundo conhecimento de linha de comandos.
Proteger Endpoints de API com SSL
Um fator frequentemente ignorado: os endpoints HTTP não encriptados são mais suscetíveis a ataques de replay e preenchimento de credenciais, que impulsionam erros 429 induzidos por força bruta. Impor HTTPS com um Certificado SSL válido garante que tokens de autenticação e cookies de sessão não possam ser intercetados e reproduzidos por ferramentas automatizadas, reduzindo uma categoria de tráfego que desencadeia limitação de taxa na sua origem.
Matriz de Decisão Técnica: Escolher a Correção Certa
Utilize esta lista de verificação para encaminhar o seu diagnóstico para a solução correta:
- 429 em
/wp-login.phpou/xmlrpc.php— Reforce olimit_reqdo Nginx para esses caminhos, bloqueiexmlrpc.phpcompletamente se não for necessário, ative a proteção contra força bruta do Wordfence. - 429 em endpoints de API do seu próprio código de aplicação — Implemente backoff exponencial com análise do cabeçalho
Retry-After; adicione cache de transientes/Redis para reduzir a frequência de chamadas de saída. - 429 a afetar todos os utilizadores intermitentemente em alojamento partilhado — Migre para um VPS para recursos isolados e limites de taxa configuráveis.
- 429 de uma API de terceiros que a sua aplicação consome — Audite a frequência de chamadas, implemente filas de pedidos, armazene respostas em cache de forma agressiva e contacte o fornecedor de API para discutir aumentos de quota.
- 429 causado por um bot ou crawler específico — Bloqueie ao nível do WAF ou do
mapdo Nginx por user-agent; verifique crawlers legítimos (Googlebot) via DNS reverso antes de bloquear. - 429 a aparecer apenas no browser, não em
curl— Limpe a cache do browser; verifique se existe um service worker a armazenar em cache a resposta de erro; inspecione os cabeçalhosCache-Controlna resposta 429. - 429 sem padrão identificável nos logs — Verifique os logs do CDN upstream ou do balanceador de carga; o limite pode estar a ser imposto numa camada de infraestrutura não visível nos logs da aplicação.
FAQ
Qual é a diferença entre um erro 429 e um erro 503?
Um 429 é uma rejeição deliberada e orientada por políticas emitida quando um cliente excede uma taxa de pedidos definida. Um 503 indica que o servidor está temporariamente incapaz de processar pedidos devido a sobrecarga ou manutenção. A correção para um 429 é o ajuste do limite de taxa ou a correção do comportamento do cliente; a correção para um 503 é o escalonamento de capacidade ou a recuperação do serviço.
Devo sempre aumentar os limites de taxa quando vejo um 429?
Não. Aumentar os limites só é apropriado quando tráfego legítimo está a ser bloqueado. Se o 429 for causado por bots, tentativas de força bruta ou um script mal configurado, aumentar o limite agrava o problema ao permitir mais tráfego malicioso. Identifique sempre a origem primeiro.
O que faz o cabeçalho Retry-After e devo sempre incluí-lo?
O cabeçalho Retry-After informa o cliente quantos segundos deve aguardar antes de tentar novamente. O RFC 6585 recomenda incluí-lo em cada resposta 429. Clientes HTTP e consumidores de API bem comportados irão respeitá-lo, reduzindo as tempestades de retry que agravam o problema original de limitação de taxa.
Um erro 429 pode prejudicar o meu SEO?
Sim, se o Googlebot receber respostas 429 de forma consistente, reduzirá a frequência de crawl do seu site, o que pode atrasar a indexação de conteúdo novo ou atualizado. O Wordfence e plugins similares devem ser configurados para isentar crawlers Google verificados da limitação de taxa. Monitorize o relatório de Estatísticas de Crawl do Google Search Console para picos em erros de servidor.
Como posso evitar que a minha própria aplicação desencadeie erros 429 em APIs externas?
Implemente uma combinação de throttling proativo (limite a taxa de pedidos de saída abaixo do limiar documentado da API), cache agressiva de respostas (armazene resultados de API no Redis ou Memcached com TTLs apropriados) e backoff exponencial reativo (analise os cabeçalhos Retry-After e recue em conformidade). Nunca faça chamadas de API de forma síncrona em cada carregamento de página sem uma camada de cache à frente delas.
