Skip to content
bitzorcas
中EN

Reference

Multi-Tenant Rate Limiting and Anti-Scraping Protection

Master BitzOrcas.Modern enterprise rate limiting. Learn ASP.NET Core RateLimiter partition strategies (Sliding Window / Token Bucket), tenant quota isolation, and 429 guards.

Last updated

In high-concurrency multi-tenant SaaS platforms without granular rate limiting, a single rogue or misconfigured tenant can take down the entire cluster:

  • Noisy Neighbor Effect: Tenant A runs an aggressive scraper exhausting the database connection pool, causing requests for Tenant B to time out;
  • Credential Stuffing Attacks: Bots attacking authentication endpoints causing server CPUs to spike to 100%.

BitzOrcas.Modern incorporates fine-grained rate limiting policies partitioned by tenant and IP: Supporting Sliding Window, Token Bucket, and concurrency queues, returning standard HTTP 429 Too Many Requests.

Multi-Tenant Rate Limiting and Partition Lifecycle

Within Quota (TokensAvailable)Quota Exceeded

1. Inbound Request (Identifies TenantId / IP)

2. ASP.NET Core Rate Limiter Middleware

3. Compute Dynamic PartitionKey (e.g. sms:192.168.1.10)

4. Evaluate Quota (Sliding Window / Token Bucket)

5. Allow to Inner Pipeline and Handlers

6. Intercept & Return 429 Too Many Requests (With Retry-After)


Step 1: Binding Rate Limiting Policies on Endpoints

Bind predefined policies on commands using [GenerateEndpoint]:

SendVerificationCodeCommand.cs: Rate-Limited Command
using BitzOrcas.Domain.Results;
using BitzOrcas.Endpoint.Attributes;
using Mediator;
namespace BitzOrcas.Identity.Application.Commands;
// 1. Binds strict SMS verification rate limiting policy (max 3 requests per minute per IP)
[GenerateEndpoint(
HttpRoute.Post,
"/api/auth/send-code",
Tag = "Auth",
RateLimitPolicy = "smsVerificationPolicy")]
// 2. Contract record mapped to Minimal API with automated rate limiting guard
public sealed record SendVerificationCodeCommand(string PhoneNumber) : ICommand<Result>;

Step 2: Configuring Tenant-Aware Rate Limit Partitions

Register partitioned rate limiters in application startup:

RateLimitingConfiguration.cs: Policy Configuration
using System.Threading.RateLimiting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
public static class RateLimitingConfiguration
{
public static IServiceCollection AddAppRateLimiting(this IServiceCollection services)
{
// Register standard ASP.NET Core RateLimiter
services.AddRateLimiter(options =>
{
// Configure sliding window for verification codes
options.AddPolicy("smsVerificationPolicy", httpContext =>
{
// 1. Partition rate limiter by client IP address
var clientIp = httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
return RateLimitPartition.GetSlidingWindowLimiter(
partitionKey: $"sms:{clientIp}",
factory: _ => new SlidingWindowRateLimiterOptions
{
PermitLimit = 3,
Window = TimeSpan.FromMinutes(1),
SegmentsPerWindow = 6,
QueueLimit = 0
});
});
// Return standard 429 status code
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
});
return services;
}
}

Summary

BitzOrcas rate limiting shields production clusters:

  • Noisy Neighbor Elimination: Dynamic tenant and IP partitions safeguard cluster health;
  • Native AOT Ready: Built directly on .NET 10 System.Threading.RateLimiting with zero reflection;
  • Standard Protocol Compliance: 429 status and Retry-After headers instruct clients on safe retry intervals.

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%