Redis  

Building Distributed Rate Limiting with Redis and YARP Reverse Proxy

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.

AlgorithmCharacteristics
Fixed WindowSimple implementation with fixed time intervals
Sliding WindowSmoother request distribution
Token BucketAllows controlled bursts
Leaky BucketProduces 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:

Tenant TierExample Policy
FreeLower request allowance
StandardModerate request allowance
EnterpriseHigher request allowance

Exact thresholds should reflect business requirements and service capacity.

Security Considerations

Distributed rate limiting complements, but does not replace, other security measures.

Continue enforcing:

  • Authentication

  • Authorization

  • Input validation

  • TLS encryption

  • Audit logging

Rate limiting protects service availability rather than controlling user permissions.

Comparison of Rate-Limiting Approaches

ApproachAdvantagesLimitations
In-MemorySimple implementationNot suitable for multiple application instances
Redis-BasedShared limits across instancesRequires external infrastructure
Gateway-BasedCentralized enforcementGateway becomes a critical component
Cloud Provider ServicesManaged infrastructurePlatform-specific capabilities

Organizations often combine gateway-based enforcement with distributed storage for consistency.

Common Mistakes

MistakeBetter Approach
Using in-memory counters in distributed deploymentsStore counters in Redis
Applying limits after business logicEvaluate limits before routing requests
Identifying clients only by IP addressPrefer authenticated identities where available
Ignoring Redis availabilityPlan for failure scenarios and monitoring
Logging sensitive authentication dataLog operational metadata instead

Troubleshooting

Limits Are Not Consistent

Verify:

  • Shared Redis instance

  • Consistent client identifiers

  • Key expiration configuration

  • Load balancer behavior

All application instances should reference the same distributed counter.

High Redis Latency

Investigate:

  • Network connectivity

  • Redis resource utilization

  • Connection pooling

  • Command execution times

Performance issues may originate from infrastructure rather than the application.

Unexpected HTTP 429 Responses

Check:

  • Client identification logic

  • Rate-limit policies

  • Authentication state

  • Retry behavior

Ensure policies match the intended workload.

Best Practices

  • Apply rate limiting at the gateway whenever practical.

  • Use Redis for distributed request counters.

  • Select client identifiers carefully.

  • Monitor Redis and gateway health.

  • Keep rate-limit policies configurable.

  • Test under representative traffic conditions.

  • Review policies regularly as application usage evolves.

Conclusion

Distributed rate limiting is an important architectural pattern for protecting high-traffic ASP.NET Core applications. By combining Redis with YARP Reverse Proxy, organizations can enforce consistent request limits across multiple application instances while maintaining scalability and operational flexibility.

A well-designed solution includes centralized request counters, careful client identification, continuous monitoring, and configurable policies. Together, these practices help improve application resilience, support fair resource usage, and protect backend services from excessive traffic without introducing unnecessary complexity.

Frequently Asked Questions

Why isn't in-memory rate limiting suitable for distributed applications?

Each application instance maintains its own counters, so requests distributed across multiple instances can bypass intended limits. A shared data store such as Redis provides consistent counting across the deployment.

Why use YARP for rate limiting?

YARP acts as a reverse proxy, allowing requests to be evaluated before reaching backend services. This helps reduce unnecessary processing and centralizes traffic management.

Should rate limits be based on IP addresses?

IP-based limits may be appropriate in some scenarios, but authenticated user identifiers, API keys, or tenant identifiers often provide more reliable and fair enforcement, especially in enterprise applications.

Can Redis become a single point of failure?

It can if deployed without appropriate resilience measures. Production environments typically use high-availability configurations, monitoring, and recovery strategies to reduce the impact of infrastructure failures.