Allegro.Extensions.RateLimiting 1.2.0

Prefix Reserved
dotnet add package Allegro.Extensions.RateLimiting --version 1.2.0                
NuGet\Install-Package Allegro.Extensions.RateLimiting -Version 1.2.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Allegro.Extensions.RateLimiting" Version="1.2.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Allegro.Extensions.RateLimiting --version 1.2.0                
#r "nuget: Allegro.Extensions.RateLimiting, 1.2.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Allegro.Extensions.RateLimiting as a Cake Addin
#addin nuget:?package=Allegro.Extensions.RateLimiting&version=1.2.0

// Install Allegro.Extensions.RateLimiting as a Cake Tool
#tool nuget:?package=Allegro.Extensions.RateLimiting&version=1.2.0                

Allegro.Extensions.RateLimiting

RateLimiter allows specifying precise limit of operations performed per configured interval (for example per second). After the limit is reached, the limiter will delay next executions until next interval period.

Note on distributed scenarios

Rate limiter has no distributed state. It will work in following scenarios:

  • there is only one service instance using rate limiter,
  • if there are many instances, each of them will limit the rate individually (for example with 4 replicas and MaxRate=10k the total MaxRate will be 40k ops/s).

How to use the RateLimiter

When creating a RateLimiter, you specify how many operation units in what interval is allowed. Operation unit is an abstract measure of operation cost (such as CosmosDB RU consumption). If all the operations are identical in terms of cost, or you cannot estimate their cost, you could just assume that each operation is equal to 1 operation unit. After the limit is reached, the limiter will delay next operations until next interval period (see example below).

There are several ways to pass operation cost to the rate limiter:

  • If you use ExecuteAsync method, the cost is assumed to be 1. This is useful for simple scenarios such as "I want to execute max X operations per Y period".
  • If you use ExecuteWeightedAsync method, you can pass the cost of the operation using weight parameter.
  • If you use ExecuteWithEstimatedWeightAsync method, you need to pass operation name and a callback function that will calculate the cost of the operation based on the response of the operation (for example, CosmosDB returns operation cost in its HTTP response). The RateLimiter keeps a mapping of operation name and their costs, so the next time you execute the same operation, its cost will already be known. Note: this works with an assumption that for each operation name, the cost is always the same. RateLimiter remembers the maximum cost given operation has ever returned.

Example (operation cost known upfront)

// creates RateLimiter that allows 12.5 operation units per 2 seconds 
var rateLimiter = new RateLimiter(12.5, TimeSpan.FromSeconds(2));

// executes operation that consumes 10 operation units
rateLimiter.ExecuteWeightedAsync(func, weight: 10);

// executes operation that consumes 2 operation units
rateLimiter.ExecuteWeightedAsync(func, weight: 2);

// executes operation that consumes 1 operation unit
rateLimiter.ExecuteAsync(func); // this will be rate-limited until next 2-second period

Example (simple RPS limiter)

// creates RateLimiter that allows 5 operations per second 
var rateLimiter = RateLimiter.WithMaxRps(5);

// executes operation that consumes 1 operation unit
rateLimiter.ExecuteAsync(func); // 1
rateLimiter.ExecuteAsync(func); // 2
rateLimiter.ExecuteAsync(func); // 3
rateLimiter.ExecuteAsync(func); // 4
rateLimiter.ExecuteAsync(func); // 5
rateLimiter.ExecuteAsync(func); // 6 - this will be rate-limited until next second

Example (CosmosDB - estimated weight)

One of the RateLimiter use cases is limiting RU usage with Azure CosmosDB. For each operation, CosmosDB returns its cost in the operation's response. As this is not known upfront, before executing the operation, we can use a simple estimation. For most use cases it can be based on the assumption, that each operation of specific type (for example Upsert document in specific collection) has the same or similar cost.

See the CosmosDB implementation for details:
https://dev.azure.com/AllegroTechies/VAbank/_git/CosmosDb?path=/src/Vabank.CosmosDb.BatchUtilities/BatchRequestHandler.cs&version=GBmain&line=42&lineEnd=46&lineStartColumn=1&lineEndColumn=1&lineStyle=plain&_a=contents

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.0 2,229 10/19/2022