Rate Limiting e Throttling em C#: Dominando os Fluxos de Requisições

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 C#: Como Proteger sua API de Sobrecargas e Manter a Sanidade dos Usuários

\n\n

Imagine: você lançou uma API incrível. O servidor voa, o banco de dados responde instantaneamente. Mas, de repente — bum! — um cliente descuidado (ou, pior ainda, um ataque DDoS) começa a bombardear seu endpoint com milhares de requisições por segundo. O servidor cai, o banco de dados sufoca, e os usuários reais veem o erro 503. Familiar?

\n\n

A solução para esse problema é o rate limiting (limitação de taxa) e o throttling (estrangulamento). Em C#, temos todas as ferramentas para implementar esses mecanismos de forma elegante e eficiente. Neste artigo, não vamos apenas abordar a teoria — vamos escrever código real, analisar algoritmos populares e descobrir qual escolher para cada tarefa específica. Apertem os cintos, vai esquentar!

\n\n

Rate Limiting vs Throttling: Qual a Diferença?

\n\n

Embora esses termos sejam frequentemente confundidos, há uma linha clara entre eles:

\n
    \n
  • Rate Limiting — é um bloqueio "rígido". Se o usuário exceder o limite (por exemplo, 100 requisições por minuto), o servidor retorna HTTP 429 (Too Many Requests). As requisições simplesmente não chegam à lógica de negócio.
  • \n
  • Throttling — é uma desaceleração "suave". O servidor aceita a requisição, mas a processa com atraso ou reduz sua prioridade. O usuário não recebe um erro, mas sua velocidade de trabalho diminui.
  • \n
\n

Em C#, podemos implementar ambas as abordagens, frequentemente combinando-as para diferentes cenários.

\n\n

Algoritmos de Rate Limiting: Do Simples ao Complexo

\n\n

Antes de escrever código, vamos entender a matemática. Existem quatro algoritmos "de ouro" que estão na base de 90% das soluções.

\n\n

1. Fixed Window (Janela Fixa)

\n

A maneira mais simples. Dividimos o tempo em intervalos fixos (por exemplo, 1 minuto) e contamos as requisições em cada janela. Assim que o contador atinge o limite — bloqueamos.

\n

Vantagens: Simplicidade de implementação. Desvantagens: Problema do "efeito de borda" (burst na transição entre janelas).

\n\n
public class FixedWindowRateLimiter\n{\n    private readonly int _limit;\n    private readonly TimeSpan _windowSize;\n    private int _counter;\n    private DateTime _windowStart;\n\n    public FixedWindowRateLimiter(int limit, TimeSpan windowSize)\n    {\n        _limit = limit;\n        _windowSize = windowSize;\n        _windowStart = DateTime.UtcNow;\n    }\n\n    public bool AllowRequest()\n    {\n        var now = DateTime.UtcNow;\n        if (now - _windowStart >= _windowSize)\n        {\n            // Reinicia a janela\n            _counter = 0;\n            _windowStart = now;\n        }\n\n        if (_counter >= _limit)\n            return false; // Too Many Requests\n\n        Interlocked.Increment(ref _counter);\n        return true;\n    }\n}
\n\n

2. Sliding Window (Janela Deslizante)

\n

Evolução da Fixed Window. Em vez de limites rígidos, consideramos as requisições em um intervalo de tempo deslizante. Geralmente implementado registrando timestamps (por exemplo, em um buffer circular).

\n

Vantagens: Suaviza picos. Desvantagens: Um pouco mais complexo de implementar, requer memória para armazenar os timestamps.

\n\n
public class SlidingWindowRateLimiter\n{\n    private readonly int _limit;\n    private readonly TimeSpan _windowSize;\n    private readonly Queue<DateTime> _timestamps = new();\n\n    public SlidingWindowRateLimiter(int limit, TimeSpan windowSize)\n    {\n        _limit = limit;\n        _windowSize = windowSize;\n    }\n\n    public bool AllowRequest()\n    {\n        var now = DateTime.UtcNow;\n        lock (_timestamps)\n        {\n            // Remove timestamps antigos\n            while (_timestamps.Count > 0 && now - _timestamps.Peek() > _windowSize)\n                _timestamps.Dequeue();\n\n            if (_timestamps.Count >= _limit)\n                return false;\n\n            _timestamps.Enqueue(now);\n            return true                

Blogs

Book Recommendations