Skip to content

Restful Rate Limiting

DodaTech 2 min read

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

  1. What status code indicates rate limiting?
  2. What header tells the client when to retry?
  3. What are the standard rate limit headers?
  4. What is the sliding window algorithm?
  5. How do you rate limit by API key vs IP?

Answers:

  1. 429 Too Many Requests.
  2. Retry-After.
  3. X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  4. Counts requests in a rolling time window, not fixed intervals.
  5. 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

What is a good default rate limit?

: 100 requests per minute for most APIs. Adjust based on your resources.

Should rate limits be per-endpoint or per-API?

: Both. Global limits for overall protection, per-endpoint limits for heavy endpoints.

How do I communicate rate limits to clients?

: Rate limit headers in every response and documentation.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro