Safeguard
Security Guides•

How do you safely test whether an API's rate limits work?

Test limits with a short run: one account, one sensitive endpoint, a small burst and a stop rule. Also check batching, which can bypass per-request limits.

Safeguard Security Team
7 min read

Test rate limits with a small, scoped burst against one endpoint using one test account, and stop at the first throttle response. You are proving a limit exists, not stress testing. Check sensitive actions first, then look for bypasses such as batching or alternate hosts.

What a limit test should prove

OWASP's API risk for unrestricted resource consumption lists the controls to look for: rate limits per client within a time frame, stricter ones for sensitive endpoints, caps on payload and parameter sizes, and server-side validation of record counts. Throttling for operations such as one-time password validation and password recovery is called out specifically.

So a good test asks four questions:

  1. Does a limit exist at all on this endpoint?
  2. Is it tighter on sensitive actions than on ordinary reads?
  3. Does the API say so with a 429 response?
  4. Can the limit be sidestepped?

Keep the test safe

This is where people get into trouble. One major cloud provider's testing policy prohibits flooding, including login and API request flooding, and another prohibits network-intensive automated testing. A rate limit test that turns into a flood breaks those rules and can take down your own service.

Use a cautious method:

  • One test account, so you do not lock out real users.
  • Start with a low number of requests and raise it in steps.
  • Stop when you see the first 429 or the first slowdown.
  • Run it in a test environment where possible, and tell whoever watches production alerts.
  • Set a hard ceiling in the tool so a typo cannot multiply the traffic.

Bypasses to try

IdeaWhat you are checking
Same action through a different routeIs the limit on the endpoint or on the business action?
Older API version or beta hostDo they share the same limiter?
Batched operationsOne HTTP request carrying many operations may count as one
Changing a client identifierIs the limit tied to something the caller can change?
Concurrent requestsDoes a burst slip through before the counter updates?

The GraphQL guidance is a good example of batching. OWASP says HTTP request counts alone miss expensive queries and multi-operation requests, and recommends capping the number of operations that can be batched, and preventing batching entirely for sensitive operations such as login or OTP checks.

Reading the result

Record the number of requests allowed, the response when the limit hits, any Retry-After header, and how long until the counter resets. Also check what the 429 body reveals. It should not include internal details.

Money limits count too

The same OWASP risk page recommends spending limits or billing alerts for third-party API integrations. If your API calls a paid service on behalf of users, test whether one user can drive that spend.

Where it belongs

A rate limit regression check fits in a nightly job against a test environment: fire a small burst, expect a 429 by request N, fail otherwise.

Worked example: a login endpoint and a report export

A team wants to know whether two endpoints have working limits: the login route and a report export route that triggers a heavy database query. Here is a cautious sequence.

Preparation. They create one test account. They tell the platform owner the test will run on staging for fifteen minutes. They set the test client to a hard ceiling of 20 requests per second, so a mistake cannot become a flood. They decide the stop rule: stop at the first 429, or after 200 requests, whichever comes first.

Login endpoint test. The test client sends wrong passwords for the test account in a loop. They record the request number at which something changes. In this example the server accepts the first five attempts, then returns 429 with a Retry-After header of 60 seconds. That is a pass for the basic limit. They then check three bypasses:

  • Does the limit follow the account, or only the source address? They change the source address, as allowed in their test environment. If the limit resets, an attacker with many addresses can keep guessing.
  • Does the older v1 login route share the limiter? They test it and find it does not: v1 never returns 429. Finding one.
  • Does a batched or alternate form of the login call count once? The API has no batching, so this item is not applicable, and they note that.

Export endpoint test. Rate per second is the wrong lens here, because one request is expensive. They send three exports at once and watch the response time and server load graphs. The third request takes much longer than the first. There is no per-user concurrency cap. Finding two: the export route needs a limit on concurrent runs and on exports per hour.

What they record.

EndpointLimit foundBypass testedResult
POST login v25 attempts then 429Change source addressLimit resets, weak
POST login v1NoneNot applicableFail
POST exportNoneConcurrency of threeFail

Fixes. One shared limiter for all login versions keyed by account and address together, a lockout or slow-down for repeated failures, and a per-user cap on concurrent exports with a daily quota.

Keeping it repeatable

Turn the login test into a nightly check that sends six wrong attempts to a test account and expects a 429 on the sixth. If someone removes the limiter in a refactor, the next morning's run fails. Keep the export concurrency test manual, because it measures load and needs a person to read the graphs.

The lesson is that rate limit testing is about a few well chosen, low-volume probes against the endpoints that matter, not about volume.

Try it yourself

Open the demo and look at how an example scan labels each finding by endpoint. Imagine the login and export rows from the example above appearing there.

Click through it at your own pace, or open it full screen.

Quick check

Should a rate limit test run against production?

Avoid it where you can. If you must, use one test account, a very small burst, and prior notice to the people who watch alerts.

Is a 429 on every endpoint good enough?

Not necessarily. Login, reset and OTP endpoints need tighter limits than ordinary reads, and the limit should not be bypassable through batching or alternate routes.

How do I know the right limit number?

Start from legitimate use: the most a real user does in a minute or an hour, then add a margin. Sensitive routes such as login and password reset need much tighter limits than ordinary reads.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.