API Rate Limit Calculator
Calculate safe call volume and burn-down time from per-minute/hour limits and concurrency.
When an API enforces a rate limit like “100 requests per minute,” how fast can you send your own requests without hitting 429 (Too Many Requests)? Enter the limit (request count) and the window (seconds), and this calculator returns the allowed throughput per second, the minimum safe interval between requests (in ms), and how long it takes to send N requests safely.
It helps you set the right throttle when designing batch jobs, crawlers, webhook retries, or bulk-send scripts. It also shows how the per-worker interval changes as you add concurrent workers. To analyze response latency by percentile, see Latency Percentile Calculator; to craft a request and test it, use cURL Command Builder.
| Allowed rate | 1.6667 req/s |
|---|---|
| Minimum safe interval | 600 ms |
| Per-worker interval | 600 ms (1 workers) |
N exceeds one window's limit. You must split the sends across multiple windows to avoid 429.
| Time to send N | 300 s (05:00) |
|---|---|
| Windows needed | 5 |
| Within limit in one window | No |
The core formulas
A rate limit is defined as “limit (requests) per window (seconds).” Everything else derives from it.
- Allowed rate = limit ÷ window (req/s)
- Minimum safe interval = window ÷ limit (s) = 1000 × window ÷ limit (ms)
- Per-worker interval = concurrency × (window ÷ limit) — more workers means each must send more slowly to keep the total rate constant.
- Time to send N = N ÷ (limit ÷ window) = N × window ÷ limit (s)
Example: 100 requests/minute
With limit 100 and a 60-second window, the allowed rate is about 1.67 req/s and the minimum interval is 600 ms. Spacing each request at least 600 ms apart is safe.
- Sending 500 requests takes 500 × 60 ÷ 100 = 300 s (=05:00).
- Exceeding the limit of 100 inside one 60-second window triggers 429. For 500 requests you need at least
ceil(500/100)=5windows. - With 4 concurrent workers, the per-worker interval should be 4 × 600 ms = 2400 ms so the combined rate stays under the limit.
Bursts and token buckets
Many APIs allow a burst on top of the average rate. This tool assumes a conservative steady rate, so on a token-bucket API that permits bursts you may be able to push harder. Sticking to the safe interval, though, almost always avoids 429 regardless of the limiter design.
Published rate limits of real APIs
Drop these straight into the limit and window fields to get the safe interval for each API (representative values from the official docs; they vary by plan and endpoint).
| API | Limit / window | ≈ safe interval |
|---|---|---|
| GitHub REST (authed, core) | 5,000 / 3,600 s | 720 ms |
| GitHub Search | 30 / 60 s | 2,000 ms |
| Stripe (live) | 100 / 1 s | 10 ms |
| Slack Web API (Tier 2) | 20 / 60 s | 3,000 ms |
| OpenWeatherMap (free) | 60 / 60 s | 1,000 ms |
Reading 429 response headers
Even after the calculator gives you an interval, when a 429 actually fires you should follow the response headers rather than guess. The common ones are:
| Header | Meaning |
|---|---|
Retry-After | Seconds to wait before retrying (e.g. 30) or an HTTP date. If present, obey it above all else. |
X-RateLimit-Limit | The limit for the current window. Put this value in the calculator's “limit” field. |
X-RateLimit-Remaining | Calls left in the window. When it hits 0, stop until the window resets. |
X-RateLimit-Reset | When the window resets (usually a Unix epoch in seconds). Wait until then for the quota to recover. |
Common pitfall
- The safe interval here assumes a steady rate, not bursting the whole limit at the start of a window. If you burn the entire quota early, then fire another burst the instant the next window opens because “it must have reset by now,” your instantaneous rate doubles across the window boundary and a sliding-window limiter returns 429. Keep your instantaneous rate under the limit, not just the average.
- If the response carries a
Retry-Afterheader, follow that header rather than the calculator's number. The calculator's interval is steady-state pacing; the header is the actual wait the server is enforcing right now.