Skip to content

Rate Limit Headers — Complete X-RateLimit Implementation Guide

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Rate Limit Headers. We cover key concepts, practical examples, and best practices to help you master this topic.

Rate limit headers communicate rate limit status to clients. Standard headers include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, enabling clients to intelligently manage their request rate.

What You'll Learn

You'll learn the standard rate limit headers, how to implement them, and how clients should use them.

Why It Matters

Clients cannot manage their rate without visibility. Rate limit headers allow clients to slow down before hitting limits, reducing 429 errors and improving reliability.

Real-World Use

GitHub returns rate limit headers on every response. A client reads X-RateLimit-Remaining and, when it drops below 10, starts throttling requests. This eliminates 429 errors entirely.

Implementation

from flask import Flask, request, jsonify
import time

app = Flask(__name__)

class RateLimiter:
    def __init__(self):
        self.data = {}

    def check_limit(self, client_id, limit=100, window=60):
        now = time.time()
        if client_id not in self.data:
            self.data[client_id] = []
        self.data[client_id] = [
            t for t in self.data[client_id] if now - t < window
        ]
        if len(self.data[client_id]) >= limit:
            oldest = self.data[client_id][0]
            reset = int(oldest + window)
            return False, limit, 0, reset
        remaining = limit - len(self.data[client_id]) - 1
        self.data[client_id].append(now)
        reset = int(now + window)
        return True, limit, remaining, reset

limiter = RateLimiter()

@app.route("/api/data")
def get_data():
    client_id = request.remote_addr
    allowed, limit, remaining, reset = limiter.check_limit(client_id)
    response = jsonify({"data": "success"})
    response.headers["X-RateLimit-Limit"] = str(limit)
    response.headers["X-RateLimit-Remaining"] = str(remaining)
    response.headers["X-RateLimit-Reset"] = str(reset)
    if not allowed:
        response.status_code = 429
        response.headers["Retry-After"] = str(reset - int(time.time()))
    return response

Common Headers

Header Purpose Example
X-RateLimit-Limit Maximum requests per window 100
X-RateLimit-Remaining Requests remaining in window 87
X-RateLimit-Reset Unix timestamp when window resets 1700000000
Retry-After Seconds to wait before retry 45

Common Mistakes

| Mistake | Fix | |---------|-----| | Inconsistent header names | Clients cannot rely on standard names | Use standard X-RateLimit-* headers | | Not including headers on success | Clients only see limits on errors | Include on every response | | Missing Retry-After on 429 | Client does not know when to retry | Always include Retry-After | | Clock-based reset without skew | Client-server clock differences | Use elapsed time, not absolute time | | No rate limit documentation | Clients do not know limits exist | Document all rate limit headers |

What's Next

Learn about Retry-After strategies.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro