Skip to content

Endpoint-Based Rate Limiting — Complete Per-Route Throttling Guide

DodaTech Updated 2026-06-28 1 min read

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

Endpoint-based Rate Limiting applies different rate limits to different API endpoints. Expensive or sensitive endpoints get strict limits, while cheap read-only endpoints get generous limits.

What You'll Learn

You'll learn how to configure per-endpoint limits and why different endpoints need different limits.

Why It Matters

A search endpoint that queries 10 databases is 100x more expensive than a health check. Applying the same rate limit to both is wasteful or dangerous.

Real-World Use

GitHub API applies different rate limits: 5000/hour for general API, 30/minute for search, and 20/minute for email notifications. Expensive search operations have stricter limits.

Implementation

from flask import Flask, request, jsonify
from functools import wraps
import time

app = Flask(__name__)

ENDPOINT_LIMITS = {
    "/api/search": {"limit": 30, "window": 60},
    "/api/export": {"limit": 5, "window": 3600},
    "/api/data": {"limit": 1000, "window": 60},
    "/api/webhook": {"limit": 100, "window": 60}
}

endpoint_counts = {}

def endpoint_rate_limit(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        path = request.path
        limits = ENDPOINT_LIMITS.get(path)
        if not limits:
            limits = {"limit": 100, "window": 60}
        client_id = request.remote_addr
        now = time.time()
        key = f"{client_id}:{path}"
        if key not in endpoint_counts:
            endpoint_counts[key] = []
        endpoint_counts[key] = [
            t for t in endpoint_counts[key] if now - t < limits["window"]
        ]
        if len(endpoint_counts[key]) >= limits["limit"]:
            return jsonify({"error": "Rate limit exceeded for this endpoint"}), 429
        endpoint_counts[key].append(now)
        return f(*args, **kwargs)
    return decorated

@app.route("/api/search")
@endpoint_rate_limit
def search():
    return jsonify({"result": "search results"})

@app.route("/api/export")
@endpoint_rate_limit
def export():
    return jsonify({"result": "export started"})

Common Mistakes

| Mistake | Fix | |---------|-----| | Same limit for all endpoints | Some endpoints cost more | Analyze and set per-endpoint limits | | No limit on auth endpoints | Brute-force attacks | Strictest limits on /login, /register | | Limits not documented | Developers get blocked unexpectedly | Document limits in API docs | | No limit on bulk endpoints | Bulk operations bypass limits | Count each item in bulk as separate request | | Hardcoded limits | Cannot adjust without deploy | Store limits in config or database |

What's Next

Learn about rate limit headers (X-RateLimit).

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro