As APIs become more distributed, protecting backend services from excessive traffic is increasingly important. A single application may run across multiple instances behind a load balancer, making traditional in-memory rate limiting ineffective because each instance maintains its own request counters.
To enforce consistent request limits across all application instances, organizations commonly use a distributed data store such as Redis. Combined with YARP (Yet Another Reverse Proxy), Redis enables centralized rate limiting that scales with modern ASP.NET Core applications while protecting backend services from abuse, accidental traffic spikes, and excessive resource consumption.
In this article, you'll learn how distributed rate limiting works, how Redis and YARP complement each other, and how to design a production-ready solution for high-traffic ASP.NET Core applications.
Why Distributed Rate Limiting?
Consider an application running on three servers.
Load Balancer
│
┌─────────┼─────────┐
│ │ │
Instance1 Instance2 Instance3
If each server keeps its own request counter, a client can exceed the intended limit simply by sending requests to different instances.
Distributed rate limiting solves this problem by storing counters in a shared data store.
Common Use Cases
Distributed rate limiting is useful for:
Public APIs
AI inference endpoints
Authentication services
Payment APIs
File upload services
Partner integrations
Multi-tenant SaaS applications
Centralized limits help ensure fairness regardless of which application instance processes the request.
High-Level Architecture
Client
│
YARP Reverse Proxy
│
Redis
│
ASP.NET Core APIs
YARP receives incoming requests, checks the distributed rate limit using Redis, and forwards allowed requests to backend services.
Why Redis?
Redis is well suited for distributed rate limiting because it provides:
In-memory performance
Atomic operations
Key expiration
Distributed access
High throughput
These capabilities simplify the implementation of shared request counters.
Understanding Rate-Limiting Algorithms
Several algorithms are commonly used.
| Algorithm | Characteristics |
|---|---|
| Fixed Window | Simple implementation with fixed time intervals |
| Sliding Window | Smoother request distribution |
| Token Bucket | Allows controlled bursts |
| Leaky Bucket | Produces a steady request flow |
The appropriate algorithm depends on your traffic patterns and business requirements.
Request Flow
Client Request
│
YARP
│
Redis Counter
│
Limit Reached?
┌────┴────┐
│ │
No Yes
│ │
Forward HTTP 429
Requests exceeding the configured limit receive an appropriate response instead of reaching backend services.
Connecting to Redis
A Redis connection is typically shared throughout the application.
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect(connectionString));
Store connection information securely rather than embedding credentials directly in source code.
Creating a Rate Limiting Service
Encapsulate rate-limiting logic behind an abstraction.
public interface IRateLimiterService
{
Task<bool> AllowRequestAsync(
string clientId,
CancellationToken cancellationToken = default);
}
Separating the implementation makes the service easier to test and evolve.
Integrating with YARP
YARP supports ASP.NET Core middleware, allowing rate limiting to occur before requests reach backend APIs.
A simplified request pipeline:
Request
│
Authentication
│
Rate Limiting
│
Routing
│
Backend API
Applying limits early reduces unnecessary processing.
Identifying Clients
Rate limiting requires a consistent identifier.
Common options include:
API key
Authenticated user identifier
Client application identifier
Tenant identifier
IP address (when appropriate)
Choose an identifier that aligns with your authentication and authorization model.
Handling Exceeded Limits
When a limit is exceeded, return an appropriate response.
HTTP 429
Too Many Requests
Providing consistent responses helps client applications implement retry behavior when appropriate.
Monitoring Rate Limiting
Useful operational metrics include:
Allowed requests
Rejected requests
Active rate-limited clients
Redis latency
Request throughput
Rate-limit policy matches
Monitoring helps identify traffic spikes and potential abuse.
Multi-Tenant Rate Limiting
Many SaaS applications require tenant-specific limits.
Example:
Join the conversation! Your thoughts help the community grow.