Rate limiting, at its core, is about controlling the flow of requests to protect your systems from overload and abuse. The fundamental question isn’t if you should rate limit, but where you should apply those limits: globally or locally.

Imagine you’re running a popular API. Thousands of users are hitting your endpoints. If one user, or a small group of users, suddenly starts making an insane number of requests, they can overwhelm your entire infrastructure. This is where the choice between global and local rate limiting becomes critical.

Local Rate Limiting: The Granular Guardian

Local rate limiting applies restrictions to individual clients or specific resources. This is your first line of defense, preventing a single bad actor from taking down the whole show.

Let’s say you have an API endpoint /users/{id} that retrieves user data. You might want to limit how often a single user can fetch their own data.

Consider this Nginx configuration snippet for local rate limiting based on the client’s IP address:

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

    server {
        location /users/{id} {
            limit_req zone=mylimit burst=10 nodelay;
            proxy_pass http://user_service;
        }
    }
}

Here, $binary_remote_addr creates a unique identifier for each client IP. zone=mylimit:10m allocates 10MB of shared memory to store the state for these limits. rate=5r/s sets the core limit to 5 requests per second. burst=10 allows a temporary surge of up to 10 requests before throttling. nodelay means requests exceeding the burst limit are immediately rejected with a 503 Service Unavailable error. This configuration ensures that no single IP address can hammer the /users/{id} endpoint beyond 5 requests per second on average, with a short burst tolerance.

Why it works: Each IP address is tracked independently. If 1.2.3.4 hits the limit, it doesn’t affect 5.6.7.8. This is essential for fair usage and preventing denial-of-service attacks from a single source.

Local rate limiting is also effective when you want to protect specific, resource-intensive operations. For example, a complex search query might be limited separately from a simple data retrieval.

Global Rate Limiting: The System-Wide Sentinel

Global rate limiting applies a single limit across all clients or a broad category of requests. This is your ultimate failsafe, ensuring that even if local limits are bypassed or if the aggregate traffic becomes too much, your entire system remains operational.

Imagine your database is the bottleneck. Even if individual users are within their local limits, a sudden influx of millions of legitimate requests could still overload the database. A global limit prevents this.

Here’s how you might implement a global limit in Nginx, again, based on the total requests hitting the API gateway:

http {
    limit_req_zone $server_name zone=global_api_limit:10m rate=1000r/s; # Limit all requests to 1000/sec

    server {
        # Apply the global limit to all requests
        limit_req zone=global_api_limit burst=2000 nodelay;

        location / {
            proxy_pass http://api_gateway;
        }
    }
}

In this scenario, $server_name (or a fixed string if you’re only proxying one service) is used to define a single zone for the entire server. rate=1000r/s caps the total requests across all clients to 1000 per second. burst=2000 allows for a temporary spike.

Why it works: This limit acts as a circuit breaker for the entire system. If the sum of all local requests exceeds 1000 per second, Nginx starts rejecting requests, regardless of which client is making them. This protects downstream services from being swamped by sheer volume.

The Synergy: A Layered Defense

The most robust approach uses both local and global rate limiting in concert. Local limits provide granular control and fairness, while global limits act as a final safety net.

Consider a typical API gateway setup:

  1. Edge/CDN Level: You might have global rate limiting at your CDN to block obvious bot traffic and absorb massive volumetric attacks before they even reach your infrastructure.
  2. API Gateway: Implement local rate limits based on API keys, user IDs, or IP addresses to enforce per-client quotas and prevent abuse. Concurrently, apply a global rate limit to the gateway itself to protect backend services from aggregate load.
  3. Service Level: Individual microservices can have their own local rate limits for specific operations that are particularly resource-intensive, further refining protection.

A common mistake is to over-rely on local limits, only to find that a coordinated (or accidental) surge from many "legitimate" clients can still bring down a critical service. Conversely, a global limit that’s too aggressive can starve legitimate high-traffic users.

The key is to understand the traffic patterns and resource constraints of your specific application. Measure your system’s capacity, identify potential bottlenecks (databases, CPU, memory, network I/O), and then craft your rate limiting strategy to match. For instance, if your database can handle 5000 writes per second, your global write limit should probably be set below that, leaving room for other operations and overhead.

One aspect often overlooked is the interaction between different rate limiting strategies. For example, if you have a local limit of 100 requests per second per API key and a global limit of 1000 requests per second across all keys, and you have 20 active API keys, it’s theoretically possible for all 20 keys to hit their local limits simultaneously, totaling 2000 requests per second. In this scenario, the global limit of 1000 requests per second would be the effective ceiling, causing requests beyond that point to be rejected, even if individual keys are still within their 100 r/s allowance. This highlights the importance of setting global limits that are genuinely lower than the sum of all potential local limits, or understanding that the most restrictive limit will always win.

Choosing the right scope for rate limiting is a continuous process of monitoring, analysis, and adjustment, ensuring your services remain available and performant for everyone.

Want structured learning?

Take the full Rate-limiting course →