Rate Limiting in C# (.NET): Complete Guide to System.Threading.RateLimiting Library

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Rate Limiting in C# (.NET): System.Threading.RateLimiting Library



Rate limiting is a critical mechanism for protecting APIs, microservices, and web applications from overloads, DDoS attacks, and uncontrolled resource consumption. In the .NET ecosystem, starting with .NET 7, the built-in System.Threading.RateLimiting library provides flexible and high-performance tools for implementing various rate limiting strategies.



What is Rate Limiting and Why is it Needed?

Rate limiting allows you to control the number of operations (requests, method calls, transactions) within a specific time period. Main use cases:

  • Protecting public APIs — preventing abuse by clients.
  • Backend stabilization — evenly distributing load on databases and external services.
  • Resource savings — limiting calls to paid third-party APIs.
  • Ensuring SLA — guaranteeing equal access for all users.


Core Components of the System.Threading.RateLimiting Library

The library is built around the abstract class RateLimiter and several ready-made implementations:



1. TokenBucketRateLimiter

A classic algorithm that accumulates tokens at a specified rate (replenishment rate) and allows their use as needed. Suitable for smoothing out traffic spikes.

using System.Threading.RateLimiting;

var limiter = new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions{ TokenLimit = 100, // Maximum number of tokens TokensPerPeriod = 20, // How many tokens are added per period ReplenishmentPeriod = TimeSpan.FromSeconds(1), // Replenishment period QueueLimit = 10, // Maximum queue size QueueProcessingOrder = QueueProcessingOrder.OldestFirst});

// Usage exampleusing var lease = await limiter.AcquireAsync(cancellationToken: CancellationToken.None);if (lease.IsAcquired){ // Perform operation Console.WriteLine("Token acquired");}else{ // Handle rejection Console.WriteLine("Limit exceeded, try again later");}


2. ConcurrencyLimiter

Limits the number of concurrent operations. Ideal for controlling access to limited resources (connection pools, file descriptors).

var concurrencyLimiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions{    PermitLimit = 10,           // Maximum 10 concurrent requests    QueueLimit = 5,             // Queue up to 5 requests    QueueProcessingOrder = QueueProcessingOrder.NewestFirst});

// Usage in async contextasync Task ProcessRequestAsync(){ using var lease = await concurrencyLimiter.AcquireAsync(); if (lease.IsAcquired) { // Perform resource-intensive task await Task.Delay(1000); }}


3. FixedWindowRateLimiter

The simplest algorithm: allows N operations within a fixed time interval (e.g., 100 requests per minute). After the window ends, the counter resets.

var fixedWindow = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions{    PermitLimit = 60,               // 60 requests    Window = TimeSpan.FromMinutes(1), // per 1 minute    QueueLimit = 0,                 // No queue    AutoReplenishment = true        // Automatic window reset});

// Check limitRateLimitLease lease = fixedWindow.AttemptAcquire();if (lease.IsAcquired){ Console.WriteLine($"Remaining attempts: {lease.GetAllMetadata()}");}


4. SlidingWindowRateLimiter

Mo

Recommendations