Skip to main content
Lumos Gate Docs

Rate Limiting

Per-IP request rate limits enforced at HAProxy level. Protect against brute-force attacks, credential stuffing, and application-layer DDoS.

Overview

Rate limiting restricts the number of requests a single IP address can make to your domain within a one-minute window. It is one of the most effective defenses against brute-force attacks, credential stuffing, API abuse, and application-layer DDoS. When a client exceeds the configured limit, subsequent requests receive a 429 Too Many Requests response until the window resets.

Rate limiting runs inside the HAProxy Lua WAF module on your shield VPS. It tracks request counts per IP using a fixed window counter, requires no external services, and adds negligible latency to request processing.

Important: Rate limiting is only active when the WAF level is set to medium or high. At the low WAF level, rate limit rules exist in the database but are not included in the generated Lua script. See WAF levels for details.

How It Works

The rate limiter uses a fixed window counter per IP address:

  1. Each incoming request increments a counter for the source IP.
  2. The counter is tracked within a 60-second window from the first request.
  3. If the counter exceeds the configured limit, the request is blocked with a 429 response.
  4. When the 60-second window expires, the counter resets for that IP.
Request Timeline (limit: 100 req/min)

00:00  [Request 1]   -> Pass (count: 1)
00:01  [Request 2]   -> Pass (count: 2)
 ...
00:30  [Request 99]  -> Pass (count: 99)
00:31  [Request 100] -> Pass (count: 100)
00:32  [Request 101] -> BLOCKED (429 Too Many Requests)
 ...
01:00  Window resets  -> counter restarts
01:01  [Request 102] -> Pass (count: 1 in new window)

Internal Implementation Details

Understanding the internals helps with capacity planning:

  • Tracker capacity -- The Lua module tracks up to 50,000 unique IPs simultaneously. If this limit is reached, the entire tracker is evicted (reset) to prevent memory exhaustion. This means during a large-scale distributed attack, counters may be lost and some IPs may temporarily bypass rate limiting.
  • Cleanup cycle -- A background task runs every 5 minutes to evict IP entries that have been inactive for more than 5 minutes, freeing memory.
  • In-memory state -- Counters are stored in Lua memory within the HAProxy process. They are not persisted to disk and are lost on HAProxy restart or reload. This means a config push (which triggers a HAProxy reload) resets all rate limit counters.

Configuration

Configure rate limiting per domain:

  1. Navigate to Dashboard -> WAF.
  2. Select the domain.
  3. Go to the Rate Limiting tab.
  4. Set your desired requests-per-minute limit and enable the toggle.

You can also create rate limit rules via the API:

POST /api/waf
{
  "rule_type": "rate_limit",
  "value": "{\"requests_per_minute\": 100}",
  "domain_id": "your-domain-uuid",
  "enabled": true
}

The value field must be a JSON string containing requests_per_minute as a number between 1 and 10,000. See API Keys for authentication details.

Configuration Options

OptionDescriptionRangeDefault
Requests per minuteMaximum number of requests allowed per IP per 60-second window1 - 10,00060
EnabledToggle rate limiting on/off for the domainon/offOff

Burst Allowance

The burst setting allows short spikes above the base rate limit. This accommodates legitimate browsing behavior -- when a user loads a page, the browser may fire 20-30 requests simultaneously for HTML, CSS, JS, images, and API calls.

For example, with a limit of 100 requests/minute and a burst of 20:

  • A client can send up to 120 requests in a burst.
  • After the burst, the sustained rate must stay below 100 requests/minute.
  • This prevents false positives from normal page loads while still catching sustained abuse.

Note: The burst allowance is configured separately from the base rate and adds to the total allowed requests within a window.

Per-Domain Configuration

Each domain has its own independent rate limit settings. This is important because different services have very different traffic profiles:

Service TypeRecommended LimitRationale
Static website / blog60 req/minLow interaction, mostly page views and asset loads
Web application120 req/minForm submissions, AJAX calls, SPA navigation
REST API300 req/minProgrammatic access, higher volume
WebSocket upgrade endpoint10 req/minOne connection per session, rarely reconnects
Login / registration page10 req/minPrevent brute-force credential attacks
E-commerce checkout30 req/minLimited legitimate interactions per session

Note: These are starting recommendations. Monitor your actual traffic patterns using the WAF events log and adjust limits accordingly. Check the events for rate_limited entries from legitimate-looking IPs to identify if your limits are too aggressive.

Blocked Response

When a request is rate-limited, the client receives:

HTTP/1.1 429 Too Many Requests
Content-Type: text/plain

Rate limit exceeded

Well-behaved API clients should implement exponential backoff when receiving 429 responses. Browsers will display the response body as plain text.

Tip: If you are building an API and want clients to handle rate limiting gracefully, document your rate limit in your API documentation. Clients can then implement retry logic with appropriate backoff.

Events Logging

Every rate-limited request is logged in the WAF events with:

FieldValue
TimestampWhen the request was blocked
Source IPIP address that exceeded the limit
DomainThe domain the request targeted
Reasonrate_limited
Rule IDThe UUID of the rate limit rule that triggered

View rate-limited requests in Dashboard -> WAF -> Events. Use the events log to:

  • Identify IPs that are consistently hitting rate limits (potential attackers or misconfigured clients).
  • Determine if your limits are too aggressive (legitimate users being blocked -- look for diverse IPs hitting the limit).
  • Spot patterns in the timing and targets of rate-limited requests (e.g., login page getting hit at regular intervals suggests a bot).
  • Decide whether to escalate to the IP blacklist for persistent offenders.

Note: WAF events have a 7-day retention policy and are capped at 5,000 events per server per day. Rate limiting continues to function even when the event log cap is reached -- only the logging stops.

Real-Time Updates

Rate limit configuration changes take effect immediately through the standard config push flow:

Dashboard -> API -> Database -> WebSocket Server -> Agent -> Lua WAF regenerated -> HAProxy reload

No restart required, no downtime. The new limits apply to all subsequent requests.

Important: A config push triggers a HAProxy reload, which resets all in-memory rate limit counters. This means if you change a rate limit value, all IPs start with a fresh count. This is generally harmless but be aware that an attacker who was rate-limited will get a brief reprieve when you push any config change.

Combining with Other Protections

Rate limiting works alongside other WAF modules. Understanding the processing order is important:

Request -> IP Whitelist check (bypass all -- no rate limiting)
        -> IP Blacklist check (block before rate limiting)
        -> Bot Protection (JS challenge before rate limiting)
        -> Rate Limit check (count + enforce -- this module)
        -> OWASP rules (pattern match)
        -> Pass to origin

Key interactions:

  • IP Whitelist -- Whitelisted IPs bypass rate limiting entirely. Use this for your own monitoring services, CI/CD pipelines, and trusted partners.
  • IP Blacklist -- Blacklisted IPs are blocked before rate limiting is even checked. They do not consume rate limit counter slots. If an IP is consistently hitting rate limits, consider escalating it to the blacklist.
  • Bot Protection -- The JS challenge runs before rate limiting. Bots that fail the challenge are blocked without incrementing rate limit counters for their IP. This means enabling bot protection effectively reduces the load on the rate limiter.
  • OWASP Rules -- Pattern matching runs after rate limiting (at high WAF level only). A request that passes the rate limit check can still be blocked by OWASP rules.

Graduated Response Strategy

Rate limiting is most effective as part of a graduated response:

Normal traffic
    |
    v
Rate limiting catches the first spike (429 responses)
    |  If the IP persists...
    v
Review WAF events, identify the attacker
    |  If clearly malicious...
    v
Add IP to blacklist (403 block, no rate limit overhead)
    |  If attacks come from many IPs...
    v
Enable bot protection (JS challenge filters non-browsers)
    |  If attacks come from specific ranges...
    v
Block the CIDR range in the blacklist

This approach avoids over-blocking while progressively escalating protection as threats intensify.

Best Practices

  • Start generous, tighten gradually. Begin with higher limits (e.g., 200 req/min) and reduce based on observed traffic patterns. It is better to initially miss some attacks than to block legitimate users.

  • Monitor before enforcing. After setting limits, watch the WAF events log for a few days. If you see legitimate users being rate-limited, increase the limit or add them to the whitelist.

  • Set different limits for different domains. A public marketing site and a high-traffic API have very different normal traffic volumes. Configure each domain's rate limit independently.

  • Account for shared IPs. Users behind corporate NAT, mobile carriers, or shared proxies may share a single public IP. Hundreds of legitimate users could appear as one IP. Set your limits high enough to accommodate this, or whitelist known corporate IP ranges.

  • Use rate limiting as a graduated response. If an IP is occasionally hitting limits, rate limiting is appropriate. If an IP is consistently and aggressively attacking, escalate to the IP blacklist. See the graduated response strategy above.

  • Protect authentication endpoints. Login, registration, and password reset endpoints should have stricter rate limits (e.g., 10 req/min) to prevent brute-force attacks. Consider creating a separate domain for auth endpoints with its own rate limit, or use per-path rate limiting via custom rules.

  • Combine with bot protection. For public-facing sites, enable bot protection alongside rate limiting. The JS challenge filters out simple bots before they even reach the rate limiter, reducing noise and resource usage.

Troubleshooting

Legitimate users getting 429 errors:

  • Increase the requests-per-minute limit. Check the WAF events log to see how many requests the blocked users were actually making.
  • Increase the burst allowance if users are being blocked on initial page loads (which fire many simultaneous requests).
  • Check if the user's IP is behind a NAT or corporate proxy (many users sharing one IP). Whitelist known corporate IP ranges.
  • Add known trusted IPs (monitoring services, CI/CD) to the whitelist.

Rate limiting not blocking an attack:

  • The attacker may be using multiple IP addresses (distributed attack). Enable bot protection to filter non-browser clients, or use the IP blacklist for known bad ranges.
  • Verify that the WAF is enabled for the domain and the WAF level is set to medium or high. Rate limiting is not active at the low level.
  • Confirm the rate limit toggle is on for the specific domain.
  • Check that the agent is connected and receiving config updates (Dashboard -> Servers).
  • Remember that a recent config push resets all counters. If you just pushed a change, the attacker's counter started fresh.

Rate limit counters resetting unexpectedly:

  • Any config change (WAF rules, domain settings, SSL toggle) triggers a HAProxy reload, which resets in-memory counters.
  • If the tracker reaches 50,000 unique IPs, all entries are evicted. This can happen during large-scale attacks.
  • The 5-minute cleanup task removes entries inactive for more than 5 minutes.

Account is frozen:

  • WAF rule creation and modification require an active account. Deposit credits to unfreeze. Existing rate limit rules continue to function on the agent.

Next Steps

  • WAF Overview -- Understand the full WAF architecture and all protection modules
  • IP Blacklist -- Escalate persistent offenders from rate limiting to full IP blocks
  • Bot Protection -- Filter automated traffic before it reaches the rate limiter
  • Origin Firewall -- Ensure your origin only accepts traffic from shield VPS
  • Domains -- Configure per-domain settings including rate limits
  • Notifications -- Get alerted about attacks and anomalies
  • Architecture -- Understand the config push pipeline and HAProxy reload mechanics
  • Troubleshooting -- Common issues and solutions