Restful Rate Limiting
title: "RESTful Rate Limiting — Throttling Requests for API Stability" description: "RESTful rate limiting controls request volume using token bucket or sliding window algorithms, communicated via X-RateLimit headers and 429 status codes." date: 2026-06-28 lastmod: 2026-06-28 weight: 23 tags: [apis, restful] }
RESTful rate limiting protects API resources by limiting client request rates using token bucket or sliding window algorithms with standard rate limit headers.
What You'll Learn
- Rate limiting algorithms
- Rate limit response headers
- Rate limit enforcement
Why It Matters
Without rate limiting, a single client can overwhelm your API, degrading service for all users.
Code Examples
from time import time
from collections import defaultdict
class SlidingWindowRateLimiter:
def __init__(self, max_requests=100, window_seconds=60):
self.max_requests = max_requests
self.window = window_seconds
self.requests = defaultdict(list)
def check(self, client_id):
now = time()
window_start = now - self.window
# Remove old requests
self.requests[client_id] = [
t for t in self.requests[client_id] if t > window_start
]
# Check limit
if len(self.requests[client_id]) >= self.max_requests:
return False, self.window - (now - self.requests[client_id][0])
self.requests[client_id].append(now)
remaining = self.max_requests - len(self.requests[client_id])
return True, remaining
limiter = SlidingWindowRateLimiter(max_requests=100, window_seconds=60)
@app.before_request
def rate_limit():
client_id = request.headers.get('X-API-Key') or request.remote_addr
allowed, remaining = limiter.check(client_id)
if not allowed:
response = jsonify({
"error": "Rate limit exceeded",
"retry_after": int(remaining)
})
response.status_code = 429
response.headers['Retry-After'] = str(int(remaining))
response.headers['X-RateLimit-Limit'] = '100'
response.headers['X-RateLimit-Remaining'] = '0'
return response
# Add rate limit headers to successful responses
@app.after_request
def add_rate_limit_headers(response):
response.headers['X-RateLimit-Limit'] = '100'
response.headers['X-RateLimit-Remaining'] = str(remaining)
response.headers['X-RateLimit-Reset'] = str(int(time() + limiter.window))
return response
// Express rate limiting
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100, // 100 requests per window
standardHeaders: true,
legacyHeaders: false,
message: {
error: 'Rate limit exceeded',
retry_after: '60 seconds'
}
});
app.use('/api/', limiter);
// Per-endpoint limits
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // 5 login attempts
message: { error: 'Too many login attempts' }
});
app.post('/api/auth/login', authLimiter, loginHandler);
Common Mistakes
1. No Rate Limiting at All
Any client can overwhelm your API at no cost.
2. Rate Limiting by IP Only
IP-based limiting penalizes shared networks (office, public WiFi).
3. No Retry-After Header
Clients don't know when to retry.
4. Inconsistent Rate Limit Headers
Clients need predictable headers to build backoff logic.
5. No Rate Limit Documentation
Clients don't know limits until they hit them.
Practice Questions
- What status code indicates rate limiting?
- What header tells the client when to retry?
- What are the standard rate limit headers?
- What is the sliding window algorithm?
- How do you rate limit by API key vs IP?
Answers:
- 429 Too Many Requests.
- Retry-After.
- X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
- Counts requests in a rolling time window, not fixed intervals.
- Use API key for authenticated requests, IP for unauthenticated.
Challenge: Implement rate limiting with sliding window algorithm. Support per-API-key limits and include standard rate limit headers in responses.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro