Rate Limiting in C# (.NET): Guide to the 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): 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                    

Recommendations