Course contentsShow
← C#
Lesson 1491 of 1,90813. Real-time Communication with SignalRFree lesson

Connection Throttling and Rate Limiting

Protect server resources by limiting the rate of incoming messages per connection.

In this lesson, you will learn how to defend your SignalR hubs from resource exhaustion by implementing rate limiting on incoming client messages.

Why Throttle SignalR Connections?

Even a well-secured hub can be overwhelmed if a malicious or buggy client sends thousands of messages per second. If your hub method performs database lookups or heavy processing, these floods can saturate your CPU and memory, effectively performing a Denial of Service (DoS) attack on your server. To prevent this, we implement Rate Limiting—a strategy that enforces a "budget" on the number of messages a single connection can send within a specific timeframe.

Implementing a Token Bucket Pattern

The most robust approach for SignalR is to use a "Token Bucket" algorithm. Think of it like a bucket that refills with a set number of tokens every second. Each incoming message "consumes" a token. If the bucket is empty, the server rejects the message.

In ASP.NET Core, we can implement this efficiently using System.Threading.RateLimiting. You can attach a RateLimiter to your hub logic to inspect incoming requests before they execute your core business logic:

public class ChatHub : Hub
{
    private readonly TokenBucketRateLimiter _limiter = new(new TokenBucketRateLimiterOptions
    {
        TokenLimit = 10,
        QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
        ReplenishmentPeriod = TimeSpan.FromSeconds(1),
        TokensPerPeriod = 10
    });

    public async Task SendMessage(string message)
    {
        using var lease = _limiter.Acquire(1);
        if (!lease.IsAcquired)
        {
            throw new HubException("Rate limit exceeded. Slow down!");
        }

        // Proceed with processing...
        await Clients.All.SendAsync("ReceiveMessage", message);
    }
}

Considerations for Real-Time Systems

When throttling, you must ensure that your HubException provides meaningful feedback to the client. Unlike a standard HTTP API, a SignalR connection remains open even after a rejected message. Your client-side implementation should listen for these exceptions and implement an exponential backoff strategy, preventing it from immediately retrying and further taxing your server.

By enforcing these limits, you decouple the stability of your infrastructure from the unpredictability of client behavior.

Key Takeaway: Implement rate limiting to establish a "message budget" per connection, ensuring that your server resources remain available for legitimate traffic even during sudden spikes in client activity.