New Feature in .NET 7: Rate Limiting

.Net Tutorials
As its name implies, rate limiting limits how much of a particular resource can be accessed. An example could be that your application can send through hundreds of requests in a minute, but you are not sure if the application or database is capable of overseeing that many requests. In such a case, programmers can put a rate limiter in the application to oversee the number of requests they would like to handle in a given amount of time (such as a minute) and then reject any requests beyond that point before accessing the database.

In this manner, rate limiting allows your application to oversee a safe number of requests without (potentially) experiencing failures from a connected database.

Looking to learn .NET software development in a class or online course? We have a tutorial listing the Top Courses to Learn .NET to help you get started.

How to Use RateLimiter in .NET

The RateLimiter abstract base class is illustrated in the .NET code example below:

public abstract class RateLimiter : IAsyncDisposable, IDisposable
{
    public abstract int GetAvailablePermits();
    public abstract TimeSpan? IdleDuration { get; }

    public RateLimitLease Acquire(int permitCount = 1);
    public ValueTask WaitAsync(int permitCount = 1, CancellationToken = default);

    public void Dispose();
    public ValueTask DisposeAsync();
}

RateLimiter can be found inside the System.Threading.RateLimiting NuGet package.

Using the Acquire Method in .NET

In the following example, we acquire a permit via the Acquire method. If the permit has been acquired, we can perform a given action, or else we can make use of error handling:

RateLimiter rlMyLimiter = GetLimiter();
using RateLimitLease rlMyRateLimitLease = rlMyLimiter.Acquire(permitCount: 1);
if (rlMyRateLimitLease.IsAcquired)
{
    // Anything in here is protected by the limiter
}
else
{
    // Here, error logic could be added
}

Concurrent Rate Limiters in .NET

The next .NET code example shows a concurrent rate limiter making use of queueing permits, which checks if a permit is available or not:

RateLimiter rlMyLimiter  = new ConcurrencyLimiter(
    new ConcurrencyLimiterOptions(permitLimit: 2, queueProcessingOrder: QueueProcessingOrder.OldestFirst, queueLimit: 2));

// First thread
using RateLimitLease rlMyRateLimitLease = rlMyLimiter.Acquire(permitCount: 2);
if (rlMyRateLimitLease.IsAcquired) 
{
	//Anything in here is protected by the limiter
}
else
{
    // Here, error logic could be added for Second Thread
}

// Second Thread
using RateLimitLease rlMyRateLimitLease = await rlMyLimiter.WaitAsync(permitCount: 2);
if (rlMyRateLimitLease.IsAcquired) 
{
	//Anything in here is protected by the limiter
}
else
{
    // Here, error logic could be added for Second Thread
}

Token Bucket Rate Limiter in .NET

The next code example shows the use of a token bucket rate limiter, which developers can use to set the tokens that can get added per period, and how often this should occur:

RateLimiter rlMyLimiter = new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions(tokenLimit: 5, queueProcessingOrder: QueueProcessingOrder.OldestFirst,
    queueLimit: 1, replenishmentPeriod: TimeSpan.FromSeconds(5), tokensPerPeriod: 1, autoReplenishment: true));
using RateLimitLease rlMyRateLimitLease1 = await rlMyLimiter.WaitAsync(5);

using RateLimitLease rlMyRateLimitLease2 = await rlMyLimiter.WaitAsync();

You can learn more about the RateLimiter API in .NET from its official documentation.

Read more .NET programming tutorials and news.


Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Must Read