Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nimanikoo/Dotnet-RateLimiter/llms.txt

Use this file to discover all available pages before exploring further.

The SlidingWindowPolicy improves on the standard fixed window by subdividing the time window into smaller segments. Rather than resetting the entire permit counter at a single hard boundary, it reclaims slots segment by segment as time advances. The result is a rolling, continuously-evaluated window that smooths out bursty traffic and prevents the double-burst problem that affects fixed window strategies at their reset boundaries.

How Segments Work

The SegmentsPerWindow option divides the total window into equal sub-windows. The rate limiter tracks how many requests were made in each segment and slides the window forward one segment at a time. As the oldest segment falls out of the window, its permits are reclaimed and become available for new requests.
Window: 10 seconds / 4 segments = 2.5 seconds per segment

Time:    [seg 1][seg 2][seg 3][seg 4] → [seg 2][seg 3][seg 4][seg 5] → ...
Permits: reclaimed as each oldest segment ages out
This means the maximum burst a caller can produce is PermitLimit over any rolling 10-second period, not just within aligned clock boundaries.

Registration

The policy is registered inside AddCustomRateLimiter in RateLimiterExtensions.cs:
options.AddSlidingWindowLimiter("SlidingWindowPolicy", opt =>
{
    opt.Window = TimeSpan.FromSeconds(10);
    opt.PermitLimit = 5;
    opt.QueueLimit = 10;
    opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
    opt.SegmentsPerWindow = 4;
}).RejectionStatusCode = 429;
OptionValueMeaning
Window10 secondsTotal duration of the rolling window
PermitLimit5Maximum requests allowed within any rolling window period
QueueLimit10Maximum requests that can wait beyond the permit limit
QueueProcessingOrderOldestFirstOldest waiting requests are released first when permits free up
SegmentsPerWindow4Number of sub-windows; more segments = finer-grained sliding
RejectionStatusCode429HTTP status returned when both the limit and queue are exhausted

Segment Math

10 seconds ÷ 4 segments = 2.5 seconds per segment
Every 2.5 seconds, the window slides forward by one segment. Permits used in the segment that just exited the window are immediately freed. This means a caller who sent 5 requests 7.5 seconds ago will have 2 of those permits freed after 7.5 seconds (3 segments × 1 reclaim), rather than waiting the full 10 seconds for a hard reset.

Applying the Policy

Decorate any controller action with [EnableRateLimiting("SlidingWindowPolicy")]. From TestController.cs:
[HttpGet("slidingwindow"), EnableRateLimiting("SlidingWindowPolicy")]
public IEnumerable<WeatherForecast> TestSlidingWindow() =>
    Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();

When to Use

ScenarioRecommendation
APIs where smooth traffic distribution matters✅ SlidingWindowPolicy is ideal
Webhook consumers or event-driven ingestion endpoints✅ Prevents segment-boundary spikes
Simple single-node apps where bursts are acceptableFixedWindowPolicy may be simpler
Multi-instance / distributed deploymentsUse Redis Fixed Window instead

Fixed Window vs Sliding Window

How it resets: The counter resets all at once at the end of the window.Burst risk: A caller can fire PermitLimit requests just before a reset and another PermitLimit requests just after — resulting in 2 × PermitLimit requests in a very short span.Configuration (FixedWindowPolicy):
opt.Window = TimeSpan.FromSeconds(5);
opt.PermitLimit = 5;
opt.QueueLimit = 10;
opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
Best for: Simple, lightweight throttling on single-node apps where boundary bursts are acceptable.

Build docs developers (and LLMs) love