API Gateway Rate Limit Abuse Fix: 3 Steps That Work

Cybersecurity & Malware Intermediate 👁 7 views 📅 Jun 28, 2026

When your API gateway flags rate limit abuse, it's usually a misconfigured client or a real attack. Here's how to fix it fast.

Start Here: The 30-Second Fix

Don't panic. First, check if this is a false alarm or a real issue. Most of the time, it's a client sending requests too fast because someone forgot to set a delay in their code.

Step 1: Look at the logs. Find the client IP or API key that's triggering the abuse. In AWS API Gateway, check CloudWatch. For Nginx, check /var/log/nginx/access.log. For Kong, use kong logs. You're looking for a single client sending way more requests than usual — like 1000 per second when your limit is 100. If you see that, it's likely a bug or a scraper.

Step 2: Block the IP temporarily. In AWS, you can quickly create a WAF rule to block that IP. For Nginx, add this to your config:

location /api {
    deny 192.168.1.100;
    # rest of your config
}

For Kong, use the ACL plugin: curl -X POST http://localhost:8001/consumers/{consumer}/acls -d 'group=blocked'. This stops the abuse in seconds.

Step 3: Check if it's a legitimate client. If the IP is from a known partner or internal service, contact the dev team. They probably have a retry loop without a backoff. Tell them to add exponential backoff — it's standard stuff. If they don't, you'll keep seeing this.

Moderate Fix: 5 Minutes

If the simple fix didn't stick — maybe the client changed IPs or it's a distributed attack — you need to tighten your rate limits.

Step 1: Adjust the rate limit policy. Your current limits might be too generous. For a public API, start with 10 requests per second per user. For internal APIs, 50-100 is safe. In AWS API Gateway, go to Usage Plans and set a rate of 10 and a burst of 20. In Nginx, use the limit_req_zone directive:

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
    location /api/ {
        limit_req zone=api burst=20 nodelay;
    }
}

For Kong, set the rate-limiting plugin: curl -X POST http://localhost:8001/services/{service}/plugins \ -H 'Content-Type: application/json' \ -d '{"name": "rate-limiting", "config": {"hour": 100, "policy": "local"}}'. The key is nodelay — it drops excess requests immediately instead of queueing them. That prevents abuse.

Step 2: Add a burst limit. Burst allows short spikes without triggering abuse. Set burst to 2-3x the rate limit. But don't set it too high — I've seen people put burst at 1000 and wonder why abuse still happens. Keep burst under 50.

Step 3: Use a sliding window. Most rate limiters use a fixed window (e.g., 100 requests per hour). A determined attacker can game that by sending all 100 in the first minute. Switch to a sliding window — AWS API Gateway does this by default, but Nginx and Kong need config changes. For Nginx, you can simulate sliding window with multiple zones. For Kong, enable sliding_window in the plugin config.

Advanced Fix: 15+ Minutes

If the abuse is persistent — like a botnet or a DDoS — you need a multi-layer approach. The simple and moderate fixes won't cut it.

Step 1: Implement IP reputation filtering. Use a service like Cloudflare or AWS WAF with managed IP reputation lists. These block known malicious IPs before they hit your gateway. In AWS, create a WAF ACL with the AWSManagedRulesCommonRuleSet and AWSManagedRulesIPReputationList. It costs a bit but saves headaches.

Step 2: Add API key-based rate limiting. Instead of limiting by IP, limit by API key. This works better for mobile apps and web clients where IPs change. In Kong, use the key-auth plugin and rate-limiting plugin together. In AWS API Gateway, use usage plans with API keys. This way, even if an attacker rotates IPs, the key gets throttled.

Step 3: Set up a WAF rate-based rule. This is more aggressive than standard rate limiting. A WAF rate-based rule counts requests and blocks the IP if it exceeds a threshold within a 5-minute window. In AWS, create a rate-based rule in WAF with a limit of 2000 requests per 5 minutes. For Nginx, you can do this with the limit_req module combined with limit_conn to limit concurrent connections.

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    location /api/ {
        limit_conn addr 10;
        limit_req zone=api burst=20 nodelay;
    }
}

Step 4: Implement a CAPTCHA challenge. If the abuse is from automated scripts, add a CAPTCHA layer. Use AWS WAF with a CAPTCHA action, or Cloudflare's Turnstile. This makes it costly for bots to attack. But be careful — CAPTCHAs can hurt user experience. Only apply them after a certain number of failed requests.

Step 5: Monitor and tune. Set up alerts for rate limit violations. Use CloudWatch alarms or Grafana dashboards. Track the number of 429 errors. If you see them rising, adjust limits. But don't over-tune — I've seen admins set limits too low and break legitimate traffic. Keep a baseline of normal traffic for a week before making changes.

Final Check

After applying the fix, test with a tool like ab (Apache Bench) or wrk. Send 100 requests in 1 second and see if you get a 429 after the limit. If you don't, your config isn't right. Also check that your legitimate clients can still work — nothing worse than fixing abuse by breaking the app.

One last thing: document the fix. Write down the rate limits, the IPs blocked, and why. You'll thank yourself in 6 months when you see this again.

Was this solution helpful?