0Pricing
C# Academy · Lesson

Configuring Rate Limiting Middleware

Apply rate limits per endpoint and policy.

Configuring Rate Limiting Middleware is a free C# Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

AddRateLimiter

Configuration starts with AddRateLimiter in the service container. You define one or more named policies and an optional global rejection status code.

builder.Services.AddRateLimiter(options =>
{
    options.RejectionStatusCode =
        StatusCodes.Status429TooManyRequests;
});

A Fixed Window Policy

AddFixedWindowLimiter registers a named policy. Set the permit limit, window length and queue behavior.

options.AddFixedWindowLimiter("fixed", limiter =>
{
    limiter.PermitLimit = 100;
    limiter.Window = TimeSpan.FromMinutes(1);
    limiter.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
    limiter.QueueLimit = 0;
});

A Sliding Window Policy

AddSlidingWindowLimiter adds SegmentsPerWindow to control smoothing granularity.

options.AddSlidingWindowLimiter("sliding", limiter =>
{
    limiter.PermitLimit = 100;
    limiter.Window = TimeSpan.FromMinutes(1);
    limiter.SegmentsPerWindow = 6;
    limiter.QueueLimit = 0;
});

A Token Bucket Policy

AddTokenBucketLimiter sets the bucket size and the replenishment rate.

options.AddTokenBucketLimiter("token", limiter =>
{
    limiter.TokenLimit = 100;
    limiter.TokensPerPeriod = 20;
    limiter.ReplenishmentPeriod = TimeSpan.FromSeconds(10);
    limiter.QueueLimit = 0;
});

A Concurrency Policy

AddConcurrencyLimiter caps simultaneous requests.

options.AddConcurrencyLimiter("concurrent", limiter =>
{
    limiter.PermitLimit = 5;
    limiter.QueueLimit = 10;
    limiter.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
});

Adding the Middleware

Activate rate limiting in the pipeline with UseRateLimiter. Place it early, after routing.

var app = builder.Build();

app.UseRateLimiter();

app.MapControllers();

RequireRateLimiting

Apply a named policy to endpoints with RequireRateLimiting (minimal API) or the [EnableRateLimiting] attribute (controllers).

app.MapGet("/search", () => Results.Ok())
   .RequireRateLimiting("token");

// Controller equivalent:
// [EnableRateLimiting("token")]

Disabling on Specific Endpoints

Exempt an endpoint from a group or global limiter with DisableRateLimiting or [DisableRateLimiting].

app.MapGet("/health", () => Results.Ok())
   .DisableRateLimiting();

A Global Limiter with Partitions

GlobalLimiter applies to every request. Use PartitionedRateLimiter.Create to give each user or IP its own counter.

options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(
    context =>
    {
        var key = context.User.Identity?.Name
                  ?? context.Connection.RemoteIpAddress?.ToString()
                  ?? "anon";
        return RateLimitPartition.GetFixedWindowLimiter(key, _ =>
            new FixedWindowRateLimiterOptions
            {
                PermitLimit = 100,
                Window = TimeSpan.FromMinutes(1)
            });
    });

Customizing the Rejection

OnRejected lets you add a Retry-After header or a friendly body when a request is throttled.

options.OnRejected = async (context, token) =>
{
    if (context.Lease.TryGetMetadata(
            MetadataName.RetryAfter, out var retry))
        context.HttpContext.Response.Headers.RetryAfter =
            ((int)retry.TotalSeconds).ToString();
    await context.HttpContext.Response
        .WriteAsync("Rate limit exceeded.", token);
};

Applying to a Route Group

Attach a policy to a whole route group so every endpoint inside shares the limit.

var api = app.MapGroup("/api")
             .RequireRateLimiting("fixed");

api.MapGet("/products", () => Results.Ok());
api.MapGet("/orders", () => Results.Ok());

Quick Check

Confirm the middleware setup.

Recap

You configured rate limiting:

  • AddRateLimiter defines fixed window, sliding window, token bucket and concurrency policies.
  • UseRateLimiter activates the middleware; RequireRateLimiting applies a policy.
  • GlobalLimiter with PartitionedRateLimiter gives per-client counters.
  • OnRejected customizes the 429 response.

Next: output caching.

Frequently asked questions

Is the “Configuring Rate Limiting Middleware” lesson free?

Yes — the full text of “Configuring Rate Limiting Middleware” is free to read here on the web, and the C# Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.

What will I learn in “Configuring Rate Limiting Middleware”?

Apply rate limits per endpoint and policy. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Configuring Rate Limiting Middleware” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Rate Limiting Algorithms
  2. Configuring Rate Limiting Middleware
  3. Output Caching Basics
  4. Cache Policies and Invalidation
← Back to C# Academy