A rate limit rule is not effective by virtue of existing. DDactic regularly finds rate limit rules that fire too late (threshold above the endpoint's saturation point), use the wrong key (IP-based limit that a botnet trivially avoids), apply to the wrong scope (global limit instead of per-endpoint), or block the wrong responses (fires on POST but not GET to the same path). Each of these configuration errors produces a rule that appears in the WAF dashboard as active and configured while providing no meaningful protection.
A correctly constructed rate limit rule has five components: a scope (what paths it applies to), a key (what characteristic distinguishes requestors), a threshold (how many requests in what time window), an action (what happens when the threshold is exceeded), and a duration (how long the action persists). Getting all five right requires understanding both the endpoint being protected and the attack patterns the rule needs to stop.
Component 1: Scope
The scope defines which requests the rule counts. A scope of /api/ counts all API requests toward the same limit bucket. A scope of /api/v2/search counts only search requests. The correct granularity depends on how different the cost profiles of the covered paths are. If all paths under /api/v2/ are approximately equally expensive, a shared scope is acceptable. If /api/v2/export is 100x more expensive than /api/v2/status, they must be in separate scopes -- otherwise the export endpoint's saturation threshold determines the limit for the status endpoint, which will be far too strict.
# Overly broad scope -- both endpoints share one limit
scope: /api/v2/
threshold: 500 req/min per IP
# Correct -- separate limits matching each endpoint's cost profile
scope: /api/v2/export
threshold: 5 req/min per IP
scope: /api/v2/status
threshold: 500 req/min per IP
Component 2: Key
The key determines what makes two requests "from the same source." The most common key is source IP. This is appropriate when legitimate users have distinct IPs and when the expected attack is from a small number of sources. IP-keyed limits are ineffective against large botnets where each bot contributes a small fraction of total attack traffic. For authenticated endpoints, the correct key is the authenticated user identifier (user ID, API key, or JWT subject), because this key is stable regardless of IP changes and cannot be evaded by changing IPs. For unauthenticated endpoints, combining IP with user-agent or TLS fingerprint provides stronger keying than IP alone.
Component 3: Threshold
The threshold is the rate at which the rule fires. The correct threshold is below the endpoint's saturation point, leaving headroom for legitimate traffic while stopping attack rates. For a search endpoint that saturates at 80 requests per second, a threshold of 60 requests per minute per IP is appropriate for legitimate users. Setting the threshold at 1,000 requests per minute per IP -- which is typical for a blanket global limit -- provides no protection, since an attacker at 60 rps per IP can easily saturate the endpoint before hitting any individual IP's limit with a modest-sized botnet.
The threshold must be calibrated to the specific endpoint's saturation point
A threshold that has not been derived from measured saturation data is a guess. It may be too low (causing false positives) or too high (providing no protection). DDactic measures saturation for each endpoint and derives threshold recommendations from the measurement.
Component 4: Action
The action determines what happens to requests that exceed the threshold. Options are typically: block (return 403 or 429), challenge (return a bot-detection challenge), throttle (queue and delay the request), or log (record and pass through). For API endpoints where returning a challenge would break clients, block with a 429 status code is appropriate. For login endpoints where legitimate users might legitimately exceed the limit, a managed challenge is preferable to a hard block. The action must be compatible with the clients that legitimately use the endpoint -- a challenge presented to a REST API client produces an error, not a human response.
Component 5: Duration
The duration determines how long the action persists after the threshold is exceeded. A duration of 0 means the rule applies only to the window in which requests exceeded the limit; subsequent windows start fresh. A duration of 3600 means the IP (or user) remains blocked for an hour after the threshold is first exceeded. For DDoS mitigation, a longer duration is appropriate: attackers do not change their source IPs after hitting a rate limit; they continue with the same sources. A 5-minute duration means the rule must re-fire every 5 minutes, consuming WAF evaluation resources. A 1-hour duration blocks the attack source for the duration of most DDoS incidents.
Verify Your Rate Limit Configuration
DDactic checks all five components of each rate limit rule in your WAF and reports which rules would fail to stop a realistic attack against each endpoint.
Run a Free Scan