Rate Limiting in C# (.NET): Complete Guide to the System.Threading.RateLimiting Library
In modern web applications and microservices, it is critically important to control the load on resources. Rate Limiting is a mechanism that prevents excessive use of APIs, databases, or other components. The .NET ecosystem now includes the built-in System.Threading.RateLimiting library, which provides flexible and high-performance tools for implementing rate limiting. In this article, we will thoroughly examine its capabilities, architecture, and usage examples.
What is System.Threading.RateLimiting?
System.Threading.RateLimiting is a library included in .NET 7 and later. It provides abstractions and implementations for various rate limiting strategies. The main class is RateLimiter, which manages access to a resource, allowing or denying requests based on defined rules.
Core Concepts
- RateLimiter — the base class from which all implementations inherit.
- Acquire / TryAcquire — synchronous methods for obtaining a permit.
- AcquireAsync / WaitAsync — asynchronous methods that allow waiting for the limit to free up.
- Metadata — additional information about the limit (e.g., time until reset).
Built-in Rate Limiting Strategies
The library supports four main strategies:
1. Fixed Window
Requests are grouped into fixed-length time windows. If the limit is exceeded, requests are rejected until the next window begins.
using System.Threading.RateLimiting;
var options = new FixedWindowRateLimiterOptions{ PermitLimit = 10, Window = TimeSpan.FromSeconds(1), QueueProcessingOrder = QueueProcessingOrder.OldestFirst, QueueLimit = 0};
var limiter = new FixedWindowRateLimiter(options);
for (int i = 0; i < 15; i++){ using var lease = await limiter.AcquireAsync(); if (lease.IsAcquired) { Console.WriteLine($"Request {i} completed"); } else { Console.WriteLine($"Request {i} rejected"); }}2. Sliding Window
Similar to fixed window, but the window "slides" with each request, providing smoother limiting. It is divided into segments.
var slidingOptions = new SlidingWindowRateLimiterOptions{ PermitLimit = 10, Window = TimeSpan.FromSeconds(1), SegmentsPerWindow = 4, QueueLimit = 0};
var slidingLimiter = new SlidingWindowRateLimiter(slidingOptions);3. Token Bucket
One of the most popular algorithms. The bucket holds a certain number of "tokens". Tokens are added at a specified rate. A request consumes one or more tokens. If the bucket is empty, the request waits or is rejected.
var tokenOptions = new TokenBucketRateLimiterOptions{ TokenLimit = 100, QueueLimit = 0, ReplenishmentPeriod = TimeSpan.FromSeconds(1), TokensPerPeriod = 10, AutoReplenishment = true};
var tokenLimiter = new TokenBucketRateLimiter(tokenOptions);4. Concurrency Limiter
Limits the number of concurrently executing requests. Useful for managing parallelism rather than speed.
var concurrencyOptions = new ConcurrencyLimiterOptions{ PermitLimit = 5, QueueLimit = 10};
var concurrencyLimiter = new ConcurrencyLimiter(concurrencyOptions);Using RateLimiter in ASP.NET Core
Starting with .NET 7, rate limiting can be easily integrated into ASP.NET Core middleware. Service registration and policy configuration:
// Program.csbuilder.Servi