O que e rate limiting?

E o mecanismo que limita quantas requisições um cliente pode fazer em um período.

Rate limiting, ou limitação de taxa, e a prática de restringir o número de requisições que um cliente pode fazer a uma API ou serviço em um determinado período de tempo. Sem rate limiting, um único cliente pode consumir todos os recursos do servidor, seja por acidente (bug em loop infinito) ou intencional (ataque de DDoS, scraping agressivo, abuso da API). Rate limiting protege a infraestrutura, garante que todos os clientes tenham acesso justo aos recursos, e e uma das primeiras linhas de defesa contra abusos. E uma prática tao fundamental que praticamente todas as APIs públicas do mundo a implementam, GitHub, Stripe, Twitter, Google Maps. Implementar rate limiting não e opcional para APIs em produção.

Por que rate limiting e necessário

Sem limites, um único cliente pode derrubar o serviço para todos.

Os casos de uso para rate limiting são variados. Proteção contra DDoS e ataques de força bruta em endpoints de login. Prevenção de scraping excessivo que consome banda e processamento. Garantia de fair use entre clientes em diferentes planos (free vs pago). Controle de custos em serviços que cobram por uso (APIs de LLM, por exemplo). Prevenção de bugs em clientes que entram em loop de retry. Proteção de serviços downstream mais lentos quando o gateway recebe um pico de tráfego. Em APIs públicas, e também uma ferramenta de negócio: limites mais generosos para clientes premium criam um incentivo concreto para upgrade. Sem rate limiting, o sistema opera em modo confiante de que todos os clientes se comportarao adequadamente, o que e uma suposição que a realidade sempre refuta.

Token Bucket, algoritmo

Bucket com tokens recarregáveis permite rajadas controladas dentro do limite.

Token Bucket e um dos algoritmos mais populares para rate limiting. A ideia e simples: cada cliente tem um balde (bucket) com capacidade N de tokens. Cada requisição consome um token. O balde e recarregado a uma taxa R tokens por segundo, até o máximo N. Se o balde esta vazio, a requisição e rejeitada com 429 Too Many Requests. O ponto forte do Token Bucket e que ele permite rajadas (bursts): se um cliente não fez requisições por algum tempo, seu balde esta cheio e ele pode fazer N requisições em rápida sucessão. Isso e util para clientes que tem padrão de uso em rajadas seguidas de silencio. A GitHub API usa uma váriação do Token Bucket: 5000 tokens por hora, recarregados continuamente, com capacidade de usar todos de uma vez se necessário.

Leaky Bucket, algoritmo

Fila de processamento a taxa constante elimina rajadas e suaviza o tráfego.

Leaky Bucket modela uma fila de tamanho fixo que e processada a uma taxa constante, como agua vazando de um balde com furo. Cada requisição e adicionada a fila. Se a fila esta cheia, a requisição e descartada. A fila processa requisições a uma taxa fixa R por segundo, independentemente de quantas chegam. O efeito e que o tráfego saindo do Leaky Bucket e sempre suave e previsível, mesmo que o tráfego de entrada seja em rajadas. Isso e util para proteger serviços downstream que não lidam bem com picos. A desvantagem e que não permite rajadas legitimas: mesmo um usuário que não faz requisições há horas não pode fazer muitas de uma vez, porque a fila processa a taxa fixa. Para APIs orientadas ao usuário, Token Bucket geralmente oferece melhor experiência.

Fixed Window vs Sliding Window

Fixed Window tem vulnerabilidade na borda. Sliding Window e mais preciso mas mais custoso.

Fixed Window Counter e o algoritmo mais simples: conta requisições em uma janela de tempo fixa de um minuto ou uma hora. O problema e a vulnerabilidade na borda da janela: um cliente pode fazer N requisições nos últimos 30 segundos de uma janela e N requisições nos primeiros 30 segundos da próxima janela, efetivamente doubando o limite em um período de 60 segundos. Sliding Window Log corrige isso armazenando o timestamp de cada requisição e contando apenas as que ocorreram nos últimos T segundos. E mais preciso mas consome mais memória, proporcional ao número de requisições. Sliding Window Counter e uma váriação hibrida que usa duas janelas fixas com interpolação linear para aproximar uma janela deslizante com consumo de memória constante. O Cloudflare usa uma váriação do Sliding Window em escala global.

Onde implementar rate limiting

API Gateway, middleware de aplicação ou banco de dados, cada nível tem prós e contras.

Rate limiting pode ser implementado em diferentes camadas da arquitetura. No API Gateway (Kong, AWS API Gateway, NGINX) e o lugar ideal para rate limiting global: centralizado, sem impacto no código da aplicação, aplica antes mesmo de a requisição chegar ao serviço. No middleware da aplicação (ex: AspNetCoreRateLimit no .NET, express-rate-limit no Node.js) oferece mais granularidade e acesso ao contexto da aplicação, como o ID do usuário autenticado. No Redis usando operações atomicas e a abordagem mais comum para rate limiting distribuído em microservicos, onde múltiplas instâncias precisam compartilhar contadores. Em produção, a combinação mais robusta e API Gateway para limites globais por IP e middleware com Redis para limites por usuário autenticado.

Limites diferentes por tier

Rate limits por plano criam incentivos de upgrade e protegem recursos premium.

Uma prática comum em APIs comerciais e definir limites diferentes por tier de usuário. Usuários free tem limites mais restritivos: 60 requisições por hora para a GitHub API sem autenticação, por exemplo. Usuários autenticados tem limites mais generosos: 5000 por hora no GitHub. Clientes pagos ou enterprise tem limites ainda maiores ou ilimitados em determinados endpoints. Essa estrategia serve a dois propositos: protege os recursos do serviço de abuso por usuários não identificados, e cria um incentivo concreto e mensurável para upgrade de plano. Implementar tier-based rate limiting exige que o rate limiter tenha acesso ao contexto do usuário (token JWT, API key) para identificar em qual tier ele se enquadra antes de aplicar o limite correto.

Headers HTTP padrão de resposta

Comunicar limites e estado atual via headers e essencial para a experiência do cliente.

Quando rate limiting e implementado, a API deve comunicar ao cliente o estado atual via headers HTTP padronizados. X-RateLimit-Limit indica o número máximo de requisições permitidas no período. X-RateLimit-Remaining indica quantas requisições ainda restam na janela atual. X-RateLimit-Reset indica o timestamp Unix em que a janela se reinicia e o limite e restaurado. Quando o limite e atingido, a resposta deve ser 429 Too Many Requests com um header Retry-After indicando quantos segundos o cliente deve esperar antes de tentar novamente. Esses headers permitem que clientes bem implementados se adaptem automaticamente ao rate limit, aguardando o reset em vez de continuar disparando requisições e acumulando erros. E a diferença entre uma API que frustra os desenvolvedores e uma que os ajuda a integrar corretamente.

Exemplos de APIs reais

Como GitHub, Stripe e Twitter implementam rate limiting em produção.

GitHub API usa Token Bucket: 5000 requisições por hora para usuários autenticados, 60 para não autenticados, com headers X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset em cada resposta. Stripe tem limites por tipo de endpoint, com limites mais restritivos para endpoints críticos como criação de pagamentos. A Stripe também implementa idempotency keys para que retentativas seguras não criem registros duplicados. Twitter (X) tem um dos sistemas de rate limiting mais complexos da industria, com limites diferentes por endpoint, por aplicação, por usuário e por tipo de autenticação. OpenAI API usa Token Bucket com limites por tokens por minuto além de requisições por minuto, refletindo o custo real de cada chamada ao modelo. Cada uma dessas implementações reflete as necessidades específicas do negócio e os vetores de abuso mais comuns enfrentados.

Resumo final

Rate limiting e proteção fundamental para qualquer API em produção.

Rate limiting e uma das primeiras features que qualquer API em produção precisa ter. Token Bucket e o algoritmo mais balanceado para a maioria dos casos, pois permite rajadas legitimas enquanto mantém o limite medio. Para proteção mais rigida de serviços downstream, Leaky Bucket suaviza o tráfego. API Gateway e a melhor camada para implementação centralizada, complementado por Redis para limites por usuário em microservicos. Headers padrão como X-RateLimit-Remaining e Retry-After são essenciais para que clientes se comportem bem. Tiers diferentes por plano transformam rate limiting de custo operacional em alavanca de monetização. Implementar rate limiting desde o inicio e muito mais simples do que retrofitar em um sistema que ja esta sob ataque.

Tutoriais em Video

Conceitos-chave

Rate Limit

Limitar número de requisições que um cliente pode fazer em um período, protege a API de abuso, DDoS e consumo excessivo

Token Bucket

Bucket com N tokens, cada requisição consome 1 token, bucket recarrega a taxa R/segundo, permite rajadas

Leaky Bucket

Fila de requisições que processa a taxa constante, esmaga rajadas, mais previsível

Fixed Window Counter

Contar requisições em janela fixa de 1 minuto, problema na borda da janela permite dobrar limite

Sliding Window Log

Registrar timestamp de cada requisição, mais preciso mas mais memória

Respostas HTTP

429 Too Many Requests com header Retry-After, headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset

No Instagram

@bytebytego

Reels

@bytebytego

No Facebook

No X (Twitter)

@mjovanovictech

Software architecture patterns explained

Ver post completo no X →
@mjovanovictech

System design best practices

Ver post completo no X →
@mjovanovictech

Domain events and distributed systems

Ver post completo no X →
@mjovanovictech

Building resilient distributed systems

Ver post completo no X →
@mjovanovictech

Microservices vs monolith decisions

Ver post completo no X →
@mjovanovictech

Software design fundamentals

Ver post completo no X →

O que devs dizem

Carlos M. ★★★★★

Implementamos rate limiting com Redis Token Bucket depois de um cliente com bug em produção fazer 50 mil requisições em 5 minutos e derrubar nossa API para todos os outros clientes. Agora o problema do cliente fica contido no bucket dele e os outros não percebem nada.

Patricia H. ★★★★☆

A parte mais importante foi adicionar os headers X-RateLimit-Remaining corretamente. Quando os clientes conseguem ver quantas requisições ainda tem, eles adaptam o comportamento automaticamente. Reduzimos em 70% os tickets de suporte sobre erros 429 depois de adicionar os headers.

Gustavo L. ★★★★★

Usamos tiers de rate limit como argumento de vendas para o plano premium. Mostrar que o plano pago tem 10x mais throughput com números concretos converteu muito mais do que textos vagos sobre recursos. Rate limiting virou uma feature de negócio, não só uma proteção técnica.