Request Rate Limiting
Mango is capable of limiting the number of requests per period of time to protect against denial-of-service style attacks and brute-force authentication attempts. Rate limiting is configured through the mango.properties file (or equivalent environment variables) and applies at the web server level before requests reach the application logic.
How Rate Limiting Works
The rate limiting algorithm uses a token bucket approach with two parameters:
- Burst quantity: The number of requests allowed in an initial burst before rate limiting takes effect.
- Quantity per period: The sustained rate of requests allowed after the burst is consumed.
For example, with a burst quantity of 10 and a sustained rate of 2 requests per second: a client can make 10 requests immediately, but after that, only 2 requests per second are permitted. The burst allowance replenishes over time as the rate falls below the sustained limit.
When a client exceeds the rate limit, subsequent requests receive an HTTP 429 Too Many Requests response until the rate falls back within the allowed limits.
REST API Rate Limits
Anonymous Users
REST API rate limiting for anonymous (unauthenticated) users is enabled by default. This protects public-facing endpoints from automated scanning and abuse.
rateLimit.rest.anonymous.enabled=true
rateLimit.rest.anonymous.burstQuantity=10
rateLimit.rest.anonymous.quanitity=2
rateLimit.rest.anonymous.period=1
rateLimit.rest.anonymous.periodUnit=SECONDS
| Property | Default | Description |
|---|---|---|
enabled | true | Enable or disable rate limiting for anonymous API requests. |
burstQuantity | 10 | Number of requests allowed in an initial burst. |
quanitity | 2 | Number of requests allowed per period after the burst is consumed. |
period | 1 | The length of the rate limiting period. |
periodUnit | SECONDS | The time unit for the period. Options: SECONDS, MINUTES, HOURS. |
Authenticated Users
REST API rate limiting for authenticated users is disabled by default. Enable it if you need to prevent individual users or integrations from overwhelming the server.
rateLimit.rest.user.enabled=false
rateLimit.rest.user.burstQuantity=20
rateLimit.rest.user.quanitity=10
rateLimit.rest.user.period=1
rateLimit.rest.user.periodUnit=SECONDS
| Property | Default | Description |
|---|---|---|
enabled | false | Enable or disable rate limiting for authenticated API requests. |
burstQuantity | 20 | Number of requests allowed in an initial burst. |
quanitity | 10 | Number of requests allowed per period after the burst is consumed. |
period | 1 | The length of the rate limiting period. |
periodUnit | SECONDS | The time unit for the period. |
When enabled, each authenticated user has their own independent rate limit counter. One user hitting their limit does not affect other users.
Authentication Rate Limits
Authentication attempts are rate-limited separately from general API requests. Both IP-based and username-based limiting are enabled by default to protect against brute-force password attacks.
Per-IP Address Limiting
This limits all authentication attempts originating from a single IP address, regardless of which username is being tried. This prevents an attacker from trying many different usernames from the same machine.
rateLimit.authentication.ip.enabled=true
rateLimit.authentication.ip.burstQuantity=5
rateLimit.authentication.ip.quanitity=1
rateLimit.authentication.ip.period=1
rateLimit.authentication.ip.periodUnit=MINUTES
| Property | Default | Description |
|---|---|---|
enabled | true | Enable or disable per-IP authentication rate limiting. |
burstQuantity | 5 | Number of authentication attempts allowed in an initial burst. |
quanitity | 1 | Number of authentication attempts allowed per period after the burst. |
period | 1 | The length of the rate limiting period. |
periodUnit | MINUTES | The time unit for the period. |
Per-Username Limiting
This limits authentication attempts against the same username from any IP address. This prevents distributed brute-force attacks where an attacker uses many different IPs to guess a single user's password.
rateLimit.authentication.user.enabled=true
rateLimit.authentication.user.burstQuantity=5
rateLimit.authentication.user.quanitity=1
rateLimit.authentication.user.period=1
rateLimit.authentication.user.periodUnit=MINUTES
| Property | Default | Description |
|---|---|---|
enabled | true | Enable or disable per-username authentication rate limiting. |
burstQuantity | 5 | Number of authentication attempts allowed in an initial burst. |
quanitity | 1 | Number of authentication attempts allowed per period after the burst. |
period | 1 | The length of the rate limiting period. |
periodUnit | MINUTES | The time unit for the period. |
Additional Web Server Rate Controls
Beyond the application-level rate limiting described above, Mango also supports Jetty-level DoS and QoS filters that can be configured in mango.properties. See the Mango Properties Reference for details on web.dos.* and web.qos.* settings.
Configuration Recommendations
Production Deployments
For production systems exposed to the internet:
- Keep anonymous REST API rate limiting enabled.
- Keep both authentication rate limits enabled.
- Consider enabling authenticated user rate limiting if external integrations make frequent API calls.
- Adjust burst quantities based on your expected traffic patterns.
Development Environments
For development and testing:
- You may want to increase rate limits or disable them to avoid interference during rapid testing.
- Be aware that automated test suites making many API calls can trigger rate limits.
Behind a Reverse Proxy
If Mango is running behind a reverse proxy (e.g., Nginx, Apache, HAProxy), ensure that web.forwardedHeaders.enabled=true and that web.forwardedHeaders.trustedIpRanges includes the proxy's IP address. This allows Mango to see the real client IP for per-IP rate limiting rather than the proxy's IP.
web.forwardedHeaders.enabled=true
web.forwardedHeaders.trustedIpRanges=127.0.0.0/8,::1,10.0.0.0/8
Without this configuration, all requests appear to come from the proxy IP, and rate limiting would apply collectively to all clients.
Monitoring Rate Limits
When a rate limit is exceeded, Mango logs the event. You can monitor the ma.log file for rate limit violations to identify potential attacks or misconfigured integrations. Persistent rate limit violations from a single IP may indicate an active attack and should be investigated.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Legitimate requests being blocked with HTTP 429 | The rate limit thresholds are too low for normal usage patterns | Increase the burstQuantity and quanitity values for the affected rate limit category. For authenticated users, try doubling the defaults (e.g., burstQuantity=40, quanitity=20). Monitor ma.log to confirm the 429 responses stop. |
| API automation or integration scripts hitting rate limits | Automated systems send requests faster than the configured sustained rate allows | Ensure the automation uses an authenticated session -- authenticated users have separate (and typically higher) rate limit counters. If limits are still too low, increase the authenticated user rate limits or stagger requests in the automation script with delays between calls. |
| Cannot determine which rate limit is being hit | Multiple rate limit categories exist (anonymous REST, authenticated REST, per-IP auth, per-username auth) and the 429 response does not indicate which | Check the response headers on the 429 response. Mango includes X-RateLimit-Limit and X-RateLimit-Remaining headers that indicate the limit and remaining allowance. Also check ma.log for the specific rate limit category that triggered the block. If the block occurs during login, it is an authentication rate limit; if during normal API calls, it is a REST API rate limit. |
| All users affected after one user is rate-limited | Mango is behind a reverse proxy and all requests appear to come from the proxy IP | Enable forwarded header support: set web.forwardedHeaders.enabled=true and add the proxy IP to web.forwardedHeaders.trustedIpRanges in mango.properties. This allows Mango to use the real client IP from the X-Forwarded-For header for per-IP rate limiting. |
| Login attempts blocked after a few tries | Per-IP or per-username authentication rate limits are triggered (default: 5 burst, 1 per minute) | Wait for the rate limit period to expire (1 minute by default). If legitimate users are frequently locked out, increase rateLimit.authentication.ip.burstQuantity or shorten the period. For environments where multiple users share an IP (e.g., behind a corporate NAT), increase the per-IP burst quantity. |
Related Pages
- Mango Properties Reference — All rate limiting properties and DoS/QoS filter settings
- HTTP and HTTPS Settings — Configure forwarded headers for correct client IP detection behind a proxy
- Content Security Policy — Browser-level security policies to complement server-side rate limiting
- Reverse Proxy Configuration — Ensure real client IPs are visible for per-IP rate limiting