// blog/developer/
Back to Blog
Developer · June 28, 2026 · 9 min read · Updated May 22, 2026

API Rate Limiting: Why It Exists and How to Handle 429 Errors

API Rate Limiting: Why It Exists and How to Handle 429 Errors

You are building a third-party API integration. Everything works in development. You deploy to production and start getting 429 errors. "Too Many Requests." Your application is making more API calls than the provider allows, and they are blocking the excess.

Rate limiting is how API providers protect their servers from being overwhelmed by any single consumer. It ensures fair access, prevents abuse, and keeps infrastructure costs predictable. Understanding rate limits saves you from outages, wasted dev time, and angry users.

* * *

How Rate Limiting Works

At its simplest, rate limiting counts the number of requests from a given client within a time window and rejects requests that exceed the limit.

The most common approaches:

Fixed window: Count requests in fixed time periods (e.g., 100 requests per minute). Simple to implement but has an edge case: a burst of 100 requests at the end of one window and 100 at the start of the next allows 200 requests in a short period.

Sliding window: Count requests in a rolling time period. More accurate than fixed windows but slightly more complex to implement. This is what most production APIs use.

Token bucket: Start with a bucket of tokens. Each request consumes one token. Tokens replenish at a fixed rate. This allows controlled bursts (use several tokens at once) while maintaining an average rate. AWS and many cloud providers use this approach.

Leaky bucket: Requests enter a queue that processes at a fixed rate. If the queue is full, new requests are rejected. This produces the smoothest request rate but adds latency.

When you hit a rate limit, the API returns HTTP status 429 (Too Many Requests). The response usually includes headers that tell you the limit, how many requests remain, and when the window resets.

The API Request Builder lets you test API endpoints and inspect response headers. Use it to check rate limit headers before writing your integration code.

Server rack with network traffic indicators
Server rack with network traffic indicators
* * *

Reading Rate Limit Headers

Most APIs communicate rate limit information through response headers. The naming is not standardized, but common patterns include:

` X-RateLimit-Limit: 100 # Maximum requests per window X-RateLimit-Remaining: 42 # Requests remaining in current window X-RateLimit-Reset: 1719500400 # Unix timestamp when the window resets Retry-After: 30 # Seconds to wait before retrying (on 429) `

Some APIs use different header names: - GitHub: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset - Stripe: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset - Twitter/X: x-rate-limit-limit, x-rate-limit-remaining, x-rate-limit-reset

The Retry-After header is the most important when you receive a 429 response. It tells you exactly how long to wait before sending another request. Always respect this value. Hammering an API with retries after receiving a 429 can get your API key suspended.

Inspect these headers using the API Request Builder or your browser's developer tools. Understanding the specific limits of the API you are working with prevents you from hitting those limits in production.

Format the JSON responses with the JSON Formatter to easily read error payloads that come with rate limit rejections. These payloads often contain useful information about which limit was hit and how to resolve it.

Key takeaway

Most APIs communicate rate limit information through response headers.

* * *

Strategies for Staying Within Rate Limits

Caching. The most effective strategy. If the same data is requested multiple times, cache the response and serve subsequent requests from the cache. A cache-control header of Cache-Control: max-age=3600 means you can reuse the response for an hour without making another API call.

Request batching. Many APIs support batch endpoints where you send multiple operations in a single request. Instead of 50 individual GET requests, send one batch request with 50 items. This counts as 1 request against your rate limit instead of 50.

Exponential backoff. When you receive a 429 response, wait before retrying. Start with a short wait (1 second), then double the wait time on each subsequent failure: 1s, 2s, 4s, 8s, 16s. Add random jitter (a random fraction of a second) to prevent multiple clients from retrying simultaneously.

`javascript async function fetchWithRetry(url, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch(url); if (response.status !== 429) return response; const retryAfter = response.headers.get('Retry-After'); const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, attempt) 1000 + Math.random() 1000; await new Promise(resolve => setTimeout(resolve, delay)); } throw new Error('Rate limit exceeded after max retries'); } `

Request queuing. Instead of making API calls directly, add them to a queue that processes at a controlled rate. This prevents bursts from exceeding the limit and ensures smooth, predictable API usage.

* * *

Building Rate Limiting into Your Own API

If you are building an API, implementing rate limiting is essential for reliability and cost control.

Per-user limits prevent any single user from consuming all your capacity. Set limits based on the user's plan tier: free users might get 100 requests per hour, paid users 1,000, and enterprise users 10,000.

Per-endpoint limits protect expensive operations. An endpoint that triggers a database-heavy report should have a lower limit than an endpoint that returns cached data.

Global limits protect your infrastructure from aggregate load. Even if each user is within their individual limit, thousands of users hitting your API simultaneously can overwhelm your servers.

For implementation, Redis is the standard backing store for rate limiting in production. It handles the counters and expiration natively with sub-millisecond latency:

`python # Simplified Redis rate limiter def is_rate_limited(user_id, limit=100, window=3600): key = f"ratelimit:{user_id}" current = redis.incr(key) if current == 1: redis.expire(key, window) return current > limit `

Always return informative rate limit headers so your consumers can build well-behaved integrations. Include the limit, remaining requests, and reset time. Use the Code Formatter to keep your rate limiting middleware clean and readable.

Developer debugging API responses in a terminal
Developer debugging API responses in a terminal
* * *

Rate Limiting in Common APIs

Understanding the limits of popular APIs helps you plan your integrations:

GitHub API: 5,000 requests per hour for authenticated requests, 60 for unauthenticated. GraphQL API has a separate point-based system. Generous for most use cases but easy to exceed with polling-heavy integrations.

Stripe API: 100 read requests per second, 100 write requests per second in live mode. Test mode has higher limits. Stripe is one of the more generous APIs because they benefit from you making more API calls (more transactions).

OpenAI API: Rate limits vary by model and tier. GPT-4 has lower limits than GPT-3.5. Limits are on both requests per minute (RPM) and tokens per minute (TPM). The token limit is often the binding constraint for large prompts.

Google APIs: Each service has its own limits. Google Maps allows 50 requests per second. Google Sheets API allows 60 reads per minute per user. These are generally sufficient for normal use but restrictive for batch processing.

Twitter/X API: The free tier is severely limited (1,500 tweets per month to read). Basic tier ($100/month) increases this to 10,000. The rate limits have changed frequently, making Twitter one of the less predictable APIs to integrate with.

Always check the API documentation for current limits. Limits change over time, usually in the direction of becoming more restrictive for free tiers.

* * *

Monitoring and Alerting for Rate Limits

In production, you should monitor your API usage and alert before you hit limits, not after.

Track these metrics:

Current usage vs limit. If you are consistently using 80%+ of your rate limit, you are one traffic spike away from failures. Increase your limit (upgrade your plan) or reduce your request volume (better caching, batching).

429 response count. Any 429 responses in production mean your rate limiting strategy has a gap. Track these over time. A spike in 429s correlates with degraded user experience.

Retry success rate. How often do your retries succeed? If most retries eventually succeed, your backoff strategy is working. If retries consistently fail, you are fundamentally exceeding the limit and need to reduce request volume.

Request distribution over time. Are your requests evenly spread or do they burst? Bursts hit rate limits even when average usage is well within limits. Spread requests with delays or use a token bucket rate limiter on the client side.

Log rate limit headers from every API response. When something goes wrong, these logs tell you exactly when you started approaching the limit and which requests pushed you over.

Set up alerts at 75% of your rate limit. This gives you time to investigate and adjust before users are affected. An alert at 100% (when you are already being rate limited) is too late.

Key takeaway

In production, you should monitor your API usage and alert before you hit limits, not after.

* * *

FAQ

What happens if I ignore rate limit responses and keep sending requests?

Most APIs start with 429 responses (temporary rejection). If you continue sending excessive requests, the API provider may temporarily ban your IP address or API key. Persistent abuse can lead to permanent account suspension. Some providers also reduce your rate limit after repeated violations.

Can I increase my rate limit without paying more?

Sometimes. Many API providers offer higher limits if you contact them and explain your use case. Open-source projects, academic research, and non-profit organizations often qualify for free tier increases. Enterprise plans usually come with custom rate limits negotiated as part of the contract.

Should I implement client-side rate limiting?

Yes. Do not rely solely on the API's rate limiting to control your request volume. Implement a client-side rate limiter (token bucket or leaky bucket) that keeps your requests well within the API's limits. This prevents 429 errors, which waste both your time and the API provider's resources.

How do rate limits work with webhooks?

Webhooks are push-based, meaning the API sends data to you. They are not typically subject to rate limits because you are receiving, not sending. However, if your webhook endpoint is slow and the API queues retries, you might receive a burst of requests when your endpoint recovers. Build your webhook handler to process requests quickly and queue heavy work for background processing.

Why do some APIs have different limits for reads vs writes?

Write operations (creating, updating, deleting) are more expensive for the server than reads. They involve database writes, validation, event triggers, and potential cascade effects. Read operations can often be served from cache. Setting lower limits for writes protects the most expensive operations while allowing generous read access.