Rate Limiting em PHP: como proteger sua API contra sobrecargas e bots

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Rate Limiting e Throttling em PHP: Domine o fluxo de requisições

\n\n

Imagine: você lançou uma API incrível para o seu serviço. Tudo funciona perfeitamente, até que um cliente "maluco" começa a bombardear seu servidor com milhares de requisições por segundo. Ou, pior ainda, um bot-parser decide extrair todo o seu banco de dados. Parece familiar? Se não, você teve sorte. Mas é melhor estar preparado. É aqui que entram em cena o rate limiting e o throttling — dois cavaleiros que protegerão seu backend contra sobrecargas.

\n\n

Neste artigo, vamos entender como implementar o limite de requisições em PHP, ver exemplos reais de código e descobrir qual método escolher para o seu projeto. Spoiler: você não precisará reinventar a roda, mas conhecer os algoritmos básicos é sempre útil.

\n\n

Rate Limiting vs Throttling: qual a diferença?

\n\n

Esses termos são frequentemente usados como sinônimos, mas existe uma diferença sutil entre eles.

\n\n
    \n
  • Rate Limiting — é um limite rígido. Você define: "Máximo de 100 requisições por minuto". Quando o limite é atingido, o cliente recebe um HTTP 429 Too Many Requests e é convidado a esperar.
  • \n
  • Throttling — é um controle mais suave. Em vez de bloquear, você simplesmente desacelera o processamento das requisições que excedem o limite, colocando-as em uma fila ou reduzindo sua prioridade.
  • \n
\n\n

Na prática, o throttling em PHP é frequentemente implementado com delays (sleep) ou filas, enquanto o rate limiting usa a contagem de requisições por unidade de tempo. Para a maioria dos gateways de API, a combinação de ambas as abordagens é ideal.

\n\n

Por que isso é crucial para o seu projeto?

\n\n

Existem pelo menos três motivos para implementar o limite de requisições em PHP:

\n\n
    \n
  • Proteção contra DDoS e bots — até mesmo um script simples pode derrubar um servidor se a frequência de chamadas não for controlada.
  • \n
  • Distribuição justa de recursos — um cliente "ganancioso" não deve prejudicar os demais usuários do serviço.
  • \n
  • Estabilidade e previsibilidade — você saberá qual pico de carga esperar e poderá configurar sua infraestrutura adequadamente.
  • \n
\n\n

Algoritmos de Rate Limiting: escolhendo a estratégia

\n\n

Antes de escrever código, vamos analisar três algoritmos populares. Cada um tem seus prós e contras.

\n\n

1. Fixed Window (Janela Fixa)

\n

A abordagem mais simples. Dividimos o tempo em intervalos (por exemplo, de minuto em minuto). Armazenamos quantas requisições chegaram na janela atual. Se o limite for atingido, bloqueamos até a próxima janela.

\n\n

Desvantagem: nas bordas das janelas, pode ocorrer um pico — o cliente pode enviar 100 requisições no final de um minuto e mais 100 no início do próximo, totalizando 200 em 2 segundos.

\n\n

2. Sliding Window (Janela Deslizante)

\n

Um algoritmo mais preciso. Em vez de intervalos fixos, olhamos para os últimos N segundos. As requisições "envelhecem" e saem da janela. Isso elimina os picos nas bordas.

\n\n

3. Token Bucket (Balde de Tokens)

\n

Um algoritmo elegante vindo do mundo das redes. Em um "balde" existem tokens. Cada requisição consome um token. Os tokens são reabastecidos a uma taxa definida. Se o balde estiver vazio, a requisição é rejeitada. É ideal para throttling em PHP, pois permite pequenos picos de tráfego.

\n\n

Implementação prática: do simples ao avançado

\n\n

Vamos ao código. Começaremos com um exemplo básico usando arquivos e, em seguida, veremos soluções prontas para produção.

\n\n

Rate Limiter básico com arquivos (para aprendizado)

\n\n

Este exemplo usa arquivos para armazenar contadores. Não é adequado para produção, mas demonstra perfeitamente o conceito.

\n\n
<?php\nclass SimpleRateLimiter {\n    private string $storageDir;\n    private int $maxRequests;\n    private int $windowSeconds;\n\n    public function __construct(string $storageDir, int $maxRequests = 100, int $windowSeconds = 60) {\n        $this->storageDir = rtrim($storageDir, '/') . '/';\n        $this->maxRequests = $maxRequests;\n        $this->windowSeconds =                

Blogs

Book Recommendations