{"id":4914,"date":"2026-02-18T05:34:52","date_gmt":"2026-02-18T05:34:52","guid":{"rendered":"https:\/\/softcolontechnologies.com\/blogs\/?p=4914"},"modified":"2026-02-18T05:38:06","modified_gmt":"2026-02-18T05:38:06","slug":"how-to-implement-rate-limiting-for-better-performance","status":"publish","type":"post","link":"https:\/\/www.softcolon.com\/blogs\/how-to-implement-rate-limiting-for-better-performance\/","title":{"rendered":"How to Implement Rate Limiting for Better Performance"},"content":{"rendered":"<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Introduction: What is Rate Limiting and Why You Need It<\/h2>\n<p class=\" text-lg my-6\">Imagine you run a popular website. One day, you notice your server is slowing down dramatically. Traffic is normal, but something&#8217;s wrong. Investigation reveals that one bot is making 10,000 requests per second to your login page, trying to guess user passwords. Or perhaps a legitimate partner&#8217;s integration is buggy and accidentally sends 1,000 requests per minute instead of 10.<\/p>\n<p class=\" text-lg my-6\"><strong>Rate limiting<\/strong> is a security technique that controls how many requests a single client (identified by IP address, user ID, or other criteria) can make to your application within a specific time window. It&#8217;s like a bouncer at a club who says, &#8220;You can enter 10 times per hour, but not 10 times per minute.&#8221;<\/p>\n<p class=\" text-lg my-6\">Without rate limiting:<\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Brute-force attacks<\/strong> succeed because attackers can try millions of password combinations<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>DDoS attacks<\/strong> overwhelm your server by flooding it with requests<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Buggy integrations<\/strong> accidentally consume all your server resources<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Web scrapers<\/strong> drain your database and bandwidth<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>API abuse<\/strong> prevents legitimate users from accessing your service<\/p>\n<\/li>\n<\/ul>\n<p class=\" text-lg my-6\">With rate limiting:<\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Attackers can only make limited attempts before being blocked<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Accidental traffic spikes are handled gracefully<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Your application remains available to legitimate users<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">You can identify and block abusive clients<\/p>\n<\/li>\n<\/ul>\n<p class=\" text-lg my-6\">Caddy makes implementing rate limiting simple with its built-in <code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">rate_limit<\/code> handler.<\/p>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Understanding Rate Limiting Concepts<\/h2>\n<p class=\" text-lg my-6\">Before diving into configuration, let&#8217;s understand the key concepts:<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit Components<\/h3>\n<p class=\" text-lg my-6\">A rate limit rule has three essential parts:<\/p>\n<p class=\" text-lg my-6\"><strong>1. Zone (Name of the Rate Limit Rule)<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">zone login <span class=\"hljs-punctuation\">{<\/span>\n    ...\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">The zone is just a name you give to the rate limit rule. You might have multiple zones: one for login attempts, one for API calls, one for downloads.<\/p>\n<p class=\" text-lg my-6\"><strong>2. Key (What to Count By)<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">The &#8220;key&#8221; determines what identifies a client. Common options:<\/p>\n<table>\n<thead>\n<tr>\n<th>Key<\/th>\n<th>Meaning<\/th>\n<th>Example<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">{remote_host}<\/code><\/td>\n<td>Client&#8217;s IP address<\/td>\n<td>203.0.113.10<\/td>\n<\/tr>\n<tr>\n<td><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">{http.request.header.X-Forwarded-For}<\/code><\/td>\n<td>IP from proxy header<\/td>\n<td>192.168.1.100<\/td>\n<\/tr>\n<tr>\n<td><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">{http.request.header.Authorization}<\/code><\/td>\n<td>API token (for authenticated users)<\/td>\n<td>token-abc-123<\/td>\n<\/tr>\n<tr>\n<td><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">{http.request.header.User-Agent}<\/code><\/td>\n<td>Browser type (less reliable)<\/td>\n<td>Mozilla\/5.0&#8230;<\/td>\n<\/tr>\n<tr>\n<td><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">{http.request.cookie.sessionid}<\/code><\/td>\n<td>Session cookie (per-user tracking)<\/td>\n<td>session-xyz-789<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\" text-lg my-6\"><strong>Example:<\/strong> If you rate limit by IP address (<code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">remote_host<\/code>), each unique IP has its own counter. If you rate limit by user token, each API user has their own counter.<\/p>\n<p class=\" text-lg my-6\"><strong>3. Events and Window (How Much and How Often)<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">events <span class=\"hljs-number\">100<\/span>\nwindow <span class=\"hljs-number\">1<\/span>m\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">events<\/code> = Number of requests allowed<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">window<\/code> = Time period (1m = 1 minute, 1h = 1 hour)<\/p>\n<\/li>\n<\/ul>\n<p class=\" text-lg my-6\"><strong>Example:<\/strong> <code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">events 100, window 1m<\/code> means &#8220;allow 100 requests per minute&#8221;<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit Behavior<\/h3>\n<p class=\" text-lg my-6\">When a client exceeds the rate limit, Caddy automatically responds with <strong>HTTP 429 Too Many Requests<\/strong>, indicating the client should slow down.<\/p>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Real-World Attacks and How Rate Limiting Helps<\/h2>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Attack 1: Brute-Force Password Attack<\/h3>\n<p class=\" text-lg my-6\">An attacker tries to guess a user&#8217;s password using automated attempts.<\/p>\n<p class=\" text-lg my-6\"><strong>Without rate limiting:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Attacker attempts <span class=\"hljs-number\">1000<\/span> login tries per minute\nApplication processes all <span class=\"hljs-number\">1000<\/span> attempts\nOne of them might be correct\nUser account compromised\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>With rate limiting (10 attempts per minute):<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Attempt <span class=\"hljs-number\">1<\/span><span class=\"hljs-punctuation\">:<\/span> \u2713 Allowed\nAttempt <span class=\"hljs-number\">2<\/span><span class=\"hljs-punctuation\">:<\/span> \u2713 Allowed\n...\nAttempt <span class=\"hljs-number\">10<\/span><span class=\"hljs-punctuation\">:<\/span> \u2713 Allowed\nAttempt <span class=\"hljs-number\">11<\/span><span class=\"hljs-punctuation\">:<\/span> \u2717 Blocked (<span class=\"hljs-number\">429<\/span> Too Many Requests)\n...\nResult<span class=\"hljs-punctuation\">:<\/span> Attacker can only try <span class=\"hljs-number\">10<\/span> times\/minute instead of <span class=\"hljs-number\">1000<\/span>\nAfter <span class=\"hljs-number\">100<\/span> minutes of attempts<span class=\"hljs-punctuation\">,<\/span> still haven't found password\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Attack 2: DDoS (Distributed Denial of Service)<\/h3>\n<p class=\" text-lg my-6\">Attacker floods your server with requests from many IP addresses, making it unavailable.<\/p>\n<p class=\" text-lg my-6\"><strong>With rate limiting:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Each IP address is limited to X requests per minute\nIf any IP exceeds limit<span class=\"hljs-punctuation\">,<\/span> it's automatically blocked\nAttacker needs <span class=\"hljs-number\">100<\/span>x more resources to have the same effect\nCost of attack becomes prohibitive\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Attack 3: Accidental Abuse<\/h3>\n<p class=\" text-lg my-6\">A partner&#8217;s API integration has a bug and loops, sending 1,000 requests per second instead of 10.<\/p>\n<p class=\" text-lg my-6\"><strong>Without rate limiting:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">All <span class=\"hljs-number\">1<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-number\">000<\/span> requests hit your database\nDatabase slows down\nOther users experience latency\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>With rate limiting:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Requests <span class=\"hljs-number\">1<\/span><span class=\"hljs-number\">-100<\/span> processed\nRequest <span class=\"hljs-number\">101<\/span><span class=\"hljs-punctuation\">:<\/span> Blocked with <span class=\"hljs-number\">429<\/span> error\nPartner sees error<span class=\"hljs-punctuation\">,<\/span> fixes bug\nEveryone else continues using the app normally\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Attack 4: Web Scraping<\/h3>\n<p class=\" text-lg my-6\">Someone writes a bot to scrape all your product data.<\/p>\n<p class=\" text-lg my-6\"><strong>Without rate limiting:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Bot makes <span class=\"hljs-number\">100<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-number\">000<\/span> requests per hour\nYour bandwidth bills skyrocket\nDatabase is stressed\nLegitimate users can't access the site\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>With rate limiting:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Bot can make max <span class=\"hljs-number\">1<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-number\">000<\/span> requests per hour (if limit is set to <span class=\"hljs-number\">1<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-number\">000<\/span>)\nScraping takes <span class=\"hljs-number\">100<\/span> hours instead of <span class=\"hljs-number\">1<\/span> hour\nBot probably gives up\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Pattern 1: Basic Rate Limiting for Entire Domain<\/h2>\n<p class=\" text-lg my-6\">Apply the same rate limit to all requests to your domain.<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Simple Rate Limit: 100 Requests Per Minute<\/h3>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone general <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">100<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>How it works:<\/strong><\/p>\n<ol class=\"list-decimal ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Each client IP address has its own counter<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Every request increments that IP&#8217;s counter<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Counter resets every minute<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">If counter exceeds 100 in a minute, requests are blocked with HTTP 429<\/p>\n<\/li>\n<\/ol>\n<p class=\" text-lg my-6\"><strong>Real-world example:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Client A (<span class=\"hljs-number\">203.0<\/span><span class=\"hljs-number\">.113<\/span><span class=\"hljs-number\">.10<\/span>) makes <span class=\"hljs-number\">50<\/span> requests \u2192 Allowed (under <span class=\"hljs-number\">100<\/span>)\nClient B (<span class=\"hljs-number\">198.51<\/span><span class=\"hljs-number\">.100<\/span><span class=\"hljs-number\">.20<\/span>) makes <span class=\"hljs-number\">100<\/span> requests \u2192 Allowed (exactly <span class=\"hljs-number\">100<\/span>)\nClient C (<span class=\"hljs-number\">192.0<\/span><span class=\"hljs-number\">.2<\/span><span class=\"hljs-number\">.30<\/span>) makes <span class=\"hljs-number\">120<\/span> requests \u2192 First <span class=\"hljs-number\">100<\/span> allowed<span class=\"hljs-punctuation\">,<\/span> next <span class=\"hljs-number\">20<\/span> blocked (<span class=\"hljs-number\">429<\/span>)\nAfter <span class=\"hljs-number\">1<\/span> minute<span class=\"hljs-punctuation\">:<\/span> All counters reset\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Conservative Rate Limit: 50 Per Hour<\/h3>\n<p class=\" text-lg my-6\">For static content or read-heavy operations:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone general <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">50<\/span>\n            window <span class=\"hljs-number\">1<\/span>h\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">This allows 50 requests per hour per IP (about 1 request per minute on average).<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Generous Rate Limit: 1000 Per Minute<\/h3>\n<p class=\" text-lg my-6\">For high-traffic applications or APIs:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone api <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">1000<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Different Limits Per Time Window<\/h3>\n<p class=\" text-lg my-6\">Combine multiple rate limit rules (short burst + long sustained):<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone burst <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">50<\/span>\n            window <span class=\"hljs-number\">10<\/span>s\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone sustained <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">1000<\/span>\n            window <span class=\"hljs-number\">1<\/span>h\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">This allows:<\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">50 requests per 10 seconds (prevents sudden bursts)<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">1,000 requests per hour (reasonable daily usage)<\/p>\n<\/li>\n<\/ul>\n<p class=\" text-lg my-6\">A normal user can make their daily requests, but a bot trying to scrape everything at once is blocked.<\/p>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Pattern 2: Rate Limit Specific Routes Only<\/h2>\n<p class=\" text-lg my-6\">Don&#8217;t apply rate limiting to your entire application. Instead, protect only sensitive routes.<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit Login Endpoint<\/h3>\n<p class=\" text-lg my-6\">The <code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">\/login<\/code> endpoint is vulnerable to brute-force attacks. Protect it aggressively:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    handle_path \/login* <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone login <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">10<\/span>\n                window <span class=\"hljs-number\">1<\/span>m\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle <span class=\"hljs-punctuation\">{<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Logic:<\/strong><\/p>\n<ol class=\"list-decimal ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Requests to <code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">\/login*<\/code> (matches \/login, \/login\/, \/login\/forgot-password, etc.):<\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Limited to 10 attempts per minute per IP<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">After 10 attempts in a minute, receive 429 error<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">All other routes:<\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">No rate limiting applied<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Users can load the homepage, browse products, etc. normally<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\" text-lg my-6\"><strong>Real-world protection:<\/strong><\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">Attacker trying to brute-force password<span class=\"hljs-punctuation\">:<\/span>\n  Attempt <span class=\"hljs-number\">1<\/span><span class=\"hljs-number\">-10<\/span><span class=\"hljs-punctuation\">:<\/span> Processing login attempts\n  Attempt <span class=\"hljs-number\">11<\/span><span class=\"hljs-punctuation\">:<\/span> Blocked (<span class=\"hljs-number\">429<\/span> Too Many Requests)\n  Attempt <span class=\"hljs-number\">12<\/span><span class=\"hljs-number\">-20<\/span><span class=\"hljs-punctuation\">:<\/span> Still blocked\n  Result<span class=\"hljs-punctuation\">:<\/span> Can only try <span class=\"hljs-number\">10<\/span> passwords per minute\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit Password Reset Endpoint<\/h3>\n<p class=\" text-lg my-6\">Prevent abuse of password reset functionality:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    handle_path \/api\/auth\/password-reset <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone password_reset <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">5<\/span>\n                window <span class=\"hljs-number\">1<\/span>h\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle <span class=\"hljs-punctuation\">{<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">This allows only 5 password reset requests per hour per IP, preventing:<\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Spam (someone resetting passwords for accounts they don&#8217;t own)<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Account enumeration (discovering which emails are registered)<\/p>\n<\/li>\n<\/ul>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit API Endpoints<\/h3>\n<p class=\" text-lg my-6\">Protect your API from abuse while allowing normal usage:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    handle_path \/api\/v1<span class=\"hljs-comment\">\/* {\n        rate_limit {\n            zone api_general {\n                key {remote_host}\n                events 1000\n                window 1m\n            }\n        }\n        reverse_proxy localhost:3001\n    }\n\n    handle {\n        reverse_proxy localhost:3001\n    }\n}\n<\/span><\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">This limits API clients to 1,000 requests per minute (about 16 per second), which is reasonable for most APIs.<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit File Downloads<\/h3>\n<p class=\" text-lg my-6\">Prevent users from downloading massive amounts of files:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    handle_path \/download<span class=\"hljs-comment\">\/* {\n        rate_limit {\n            zone downloads {\n                key {remote_host}\n                events 20\n                window 1h\n            }\n        }\n        reverse_proxy localhost:3000\n    }\n\n    handle {\n        reverse_proxy localhost:3000\n    }\n}\n<\/span><\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">Allows 20 downloads per hour per IP (about 1 every 3 minutes).<\/p>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Pattern 3: Rate Limiting by Different Keys<\/h2>\n<p class=\" text-lg my-6\">Instead of identifying clients by IP, identify them by user account, API token, or other criteria.<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit by API Token (Per User)<\/h3>\n<p class=\" text-lg my-6\">When users authenticate with an API token, rate limit them individually:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone api_user <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>http.request.header.Authorization<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">1000<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3001<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Benefits:<\/strong><\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Each API user has their own quota<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Even if one user&#8217;s IP makes 1,000 requests, they only get their allocation<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Multiple users from the same office (same IP) don&#8217;t interfere with each other<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Users on mobile networks (changing IPs) aren&#8217;t penalized<\/p>\n<\/li>\n<\/ul>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit by Session Cookie (Per User)<\/h3>\n<p class=\" text-lg my-6\">For web applications where users are logged in via session cookies:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    handle_path \/api<span class=\"hljs-comment\">\/* {\n        rate_limit {\n            zone api_session {\n                key {http.request.cookie.sessionid}\n                events 500\n                window 1m\n            }\n        }\n        reverse_proxy localhost:3000\n    }\n\n    handle {\n        reverse_proxy localhost:3000\n    }\n}\n<\/span><\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Benefit:<\/strong> Anonymous users share a limit, but authenticated users have individual limits.<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Rate Limit by Custom Header<\/h3>\n<p class=\" text-lg my-6\">If clients send a custom identifier header:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone api_client <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>http.request.header.X-Client-ID<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">500<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3001<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Pattern 4: Tiered Rate Limiting<\/h2>\n<p class=\" text-lg my-6\">Different rules for different types of clients.<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Premium vs. Free Users<\/h3>\n<p class=\" text-lg my-6\">Premium users get higher limits:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    # Premium users (identified by special token)\n    handle <span class=\"hljs-punctuation\">{<\/span>\n        @premium <span class=\"hljs-punctuation\">{<\/span>\n            header X-Account-Type premium\n        <span class=\"hljs-punctuation\">}<\/span>\n\n        handle @premium <span class=\"hljs-punctuation\">{<\/span>\n            rate_limit <span class=\"hljs-punctuation\">{<\/span>\n                zone premium <span class=\"hljs-punctuation\">{<\/span>\n                    key <span class=\"hljs-punctuation\">{<\/span>http.request.header.X-API-Key<span class=\"hljs-punctuation\">}<\/span>\n                    events <span class=\"hljs-number\">10000<\/span>\n                    window <span class=\"hljs-number\">1<\/span>m\n                <span class=\"hljs-punctuation\">}<\/span>\n            <span class=\"hljs-punctuation\">}<\/span>\n            reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3001<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n\n        # Free users (default)\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone free <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>http.request.header.X-Client-ID<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">100<\/span>\n                window <span class=\"hljs-number\">1<\/span>m\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3001<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Tiers:<\/strong><\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Premium users: 10,000 requests\/minute<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Free users: 100 requests\/minute<\/p>\n<\/li>\n<\/ul>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Admin vs. Regular Users<\/h3>\n<p class=\" text-lg my-6\">Admins bypass rate limiting:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    @admin <span class=\"hljs-punctuation\">{<\/span>\n        header X-User-Role admin\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle @admin <span class=\"hljs-punctuation\">{<\/span>\n        # No rate limiting for admins\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Regular users\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone general <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">500<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle <span class=\"hljs-punctuation\">{<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Real-World Scenarios<\/h2>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Scenario 1: E-Commerce Application<\/h3>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">shop.example.com <span class=\"hljs-punctuation\">{<\/span>\n    # Aggressive rate limit on login (prevent credential stuffing)\n    handle_path \/login <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone login <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">5<\/span>\n                window <span class=\"hljs-number\">1<\/span>m\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Aggressive on password reset (prevent enumeration)\n    handle_path \/forgot-password <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone password_reset <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">3<\/span>\n                window <span class=\"hljs-number\">1<\/span>h\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Moderate on API (prevent scraping)\n    handle_path \/api<span class=\"hljs-comment\">\/* {\n        rate_limit {\n            zone api {\n                key {remote_host}\n                events 500\n                window 1m\n            }\n        }\n        reverse_proxy localhost:3000\n    }\n\n    # Normal browsing unrestricted\n    handle {\n        reverse_proxy localhost:3000\n    }\n}\n<\/span><\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Scenario 2: Public API Service<\/h3>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    # Unauthenticated requests (strict limit)\n    handle_path \/api\/v1<span class=\"hljs-comment\">\/* {\n        @unauthenticated {\n            header_regexp Authorization ^$\n        }\n\n        handle @unauthenticated {\n            rate_limit {\n                zone public {\n                    key {remote_host}\n                    events 100\n                    window 1m\n                }\n            }\n            reverse_proxy localhost:3001\n        }\n\n        # Authenticated requests (generous limit)\n        rate_limit {\n            zone authenticated {\n                key {http.request.header.Authorization}\n                events 5000\n                window 1m\n            }\n        }\n        reverse_proxy localhost:3001\n    }\n\n    handle {\n        reverse_proxy localhost:3001\n    }\n}\n<\/span><\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Scenario 3: Multi-Tenant SaaS<\/h3>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">app.example.com <span class=\"hljs-punctuation\">{<\/span>\n    # Each tenant gets their own rate limit based on their API key\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone tenant <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>http.request.header.X-Tenant-Key<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">10000<\/span>\n            window <span class=\"hljs-number\">1<\/span>h\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Burst protection (no more than <span class=\"hljs-number\">500<\/span>\/minute from one tenant)\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone tenant_burst <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>http.request.header.X-Tenant-Key<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">500<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Customizing Error Responses<\/h2>\n<p class=\" text-lg my-6\">When a client exceeds the rate limit, they get a 429 error. You can customize the message:<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Returning a JSON Error Response<\/h3>\n<p class=\" text-lg my-6\">For APIs, return JSON:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone api <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">100<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    @ratelimit_error <span class=\"hljs-punctuation\">{<\/span>\n        response_header -X-Rate-Limit-Remaining\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle @ratelimit_error <span class=\"hljs-punctuation\">{<\/span>\n        respond `<span class=\"hljs-punctuation\">{<\/span><span class=\"hljs-attr\">\"error\"<\/span><span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-string\">\"Rate limit exceeded. Maximum 100 requests per minute.\"<\/span><span class=\"hljs-punctuation\">}<\/span>` <span class=\"hljs-number\">429<\/span> <span class=\"hljs-punctuation\">{<\/span>\n            header Content-Type application\/json\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3001<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Custom HTML Page<\/h3>\n<p class=\" text-lg my-6\">For websites, return HTML:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone general <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">100<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    respond `&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;Rate Limit Exceeded&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Too Many Requests&lt;\/h1&gt;\n    &lt;p&gt;You've exceeded the rate limit. Please wait before making more requests.&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;` <span class=\"hljs-number\">429<\/span> <span class=\"hljs-punctuation\">{<\/span>\n        header Content-Type text\/html\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Handling Legitimate Traffic Spikes<\/h2>\n<p class=\" text-lg my-6\">Sometimes legitimate traffic exceeds your rate limit (news article, social media viral moment). Handle this gracefully:<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Burst-Friendly Limits<\/h3>\n<p class=\" text-lg my-6\">Allow short bursts while enforcing sustained limits:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    # Allow bursts (<span class=\"hljs-number\">1000<\/span> in <span class=\"hljs-number\">10<\/span> seconds)\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone burst <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">1000<\/span>\n            window <span class=\"hljs-number\">10<\/span>s\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Enforce sustained rate (<span class=\"hljs-number\">2000<\/span> per hour)\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone sustained <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">2000<\/span>\n            window <span class=\"hljs-number\">1<\/span>h\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">A normal user doing legitimate activity (fast page loads, form submissions) won&#8217;t hit the burst limit. A bot scraping continuously will hit the sustained limit.<\/p>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Increased Limits During High-Traffic Events<\/h3>\n<p class=\" text-lg my-6\">Temporarily increase limits during anticipated high-traffic periods:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># Normal operation\nexample.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone general <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">500<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n\n# During Black Friday \/ special events<span class=\"hljs-punctuation\">,<\/span> increase limits\n# (You'd temporarily change this)\nexample.com <span class=\"hljs-punctuation\">{<\/span>\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone general <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">2000<\/span>        # <span class=\"hljs-number\">4<\/span>x increase\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Common Mistakes to Avoid<\/h2>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Mistake 1: Rate Limiting by IP When Behind a Proxy<\/h3>\n<p class=\" text-lg my-6\">If your traffic goes through a load balancer, reverse proxy, or CDN, all traffic appears to come from the proxy&#8217;s IP, not the user&#8217;s real IP.<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u274c WRONG - Behind Cloudflare<span class=\"hljs-punctuation\">,<\/span> all users appear as Cloudflare's IP\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone api <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">100<\/span>\n        window <span class=\"hljs-number\">1<\/span>m\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Result:<\/strong> All users share one limit. After one user makes 100 requests, everyone else is blocked.<\/p>\n<p class=\" text-lg my-6\"><strong>Solution:<\/strong> Use the X-Forwarded-For header (from proxy) instead:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u2705 CORRECT\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone api <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>http.request.header.X-Forwarded-For<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">100<\/span>\n        window <span class=\"hljs-number\">1<\/span>m\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">Or for Cloudflare:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u2705 CORRECT for Cloudflare\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone api <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>http.request.header.CF-Connecting-IP<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">100<\/span>\n        window <span class=\"hljs-number\">1<\/span>m\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Mistake 2: Setting Limits Too Strict<\/h3>\n<p class=\" text-lg my-6\">If your limits are too aggressive, legitimate users get blocked:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u274c WRONG - Too strict\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone api <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">5<\/span>          # Only <span class=\"hljs-number\">5<\/span> requests per minute\n        window <span class=\"hljs-number\">1<\/span>m\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">A user paginating through results (5 clicks) instantly hits the limit.<\/p>\n<p class=\" text-lg my-6\"><strong>Solution:<\/strong> Set reasonable limits based on expected usage:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u2705 CORRECT\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone api <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">1000<\/span>       # Much more reasonable\n        window <span class=\"hljs-number\">1<\/span>m\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Mistake 3: Forgetting to Rate Limit Sensitive Endpoints<\/h3>\n<p class=\" text-lg my-6\">Leaving login, password reset, or API endpoints unprotected:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u274c WRONG - No rate limit on sensitive routes\nexample.com <span class=\"hljs-punctuation\">{<\/span>\n    handle_path \/login <span class=\"hljs-punctuation\">{<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle <span class=\"hljs-punctuation\">{<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Solution:<\/strong> Explicitly add rate limits to sensitive routes:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u2705 CORRECT\nexample.com <span class=\"hljs-punctuation\">{<\/span>\n    handle_path \/login <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone login <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">10<\/span>\n                window <span class=\"hljs-number\">1<\/span>m\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle <span class=\"hljs-punctuation\">{<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Mistake 4: Using Inconsistent Time Windows<\/h3>\n<p class=\" text-lg my-6\">Mixing different time windows makes rules confusing:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u274c CONFUSING\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone quick <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">50<\/span>\n        window <span class=\"hljs-number\">30<\/span>s\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone medium <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">100<\/span>\n        window <span class=\"hljs-number\">2<\/span>m\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone long <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">1000<\/span>\n        window <span class=\"hljs-number\">3<\/span>h\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Solution:<\/strong> Use standard time windows (10s, 1m, 1h, 1d):<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u2705 CLEAR AND UNDERSTANDABLE\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone burst <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">100<\/span>\n        window <span class=\"hljs-number\">10<\/span>s       # Burst limit\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone sustained <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">1000<\/span>\n        window <span class=\"hljs-number\">1<\/span>m        # Sustained rate\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Mistake 5: Not Testing Before Deploying<\/h3>\n<p class=\" text-lg my-6\">Deploy rate limiting in production without testing, and you might accidentally block all legitimate traffic:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\"># \u274c WRONG - Deploy without testing limits\nrate_limit <span class=\"hljs-punctuation\">{<\/span>\n    zone api <span class=\"hljs-punctuation\">{<\/span>\n        key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n        events <span class=\"hljs-number\">10<\/span>\n        window <span class=\"hljs-number\">1<\/span>m\n    <span class=\"hljs-punctuation\">}<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\"><strong>Solution:<\/strong> Test thoroughly before deploying:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-bash whitespace-pre-wrap break-words text-gray-300\"><span class=\"hljs-comment\"># Test from multiple IPs<\/span>\n<span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> {1..15}; <span class=\"hljs-keyword\">do<\/span>\n    curl https:\/\/api.example.com\/endpoint\n    <span class=\"hljs-built_in\">echo<\/span> <span class=\"hljs-string\">\"Request <span class=\"hljs-variable\">$i<\/span>\"<\/span>\n    <span class=\"hljs-built_in\">sleep<\/span> 1\n<span class=\"hljs-keyword\">done<\/span>\n\n<span class=\"hljs-comment\"># Request 11-15 should fail with 429<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Monitoring and Debugging<\/h2>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Check Rate Limit Status<\/h3>\n<p class=\" text-lg my-6\">Enable Caddy logging to see rate limit behavior:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    log <span class=\"hljs-punctuation\">{<\/span>\n        output stdout\n        format json\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone api <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">100<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">View logs:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-bash whitespace-pre-wrap break-words text-gray-300\"><span class=\"hljs-comment\"># If running as service<\/span>\n<span class=\"hljs-built_in\">sudo<\/span> journalctl -u caddy -f\n\n<span class=\"hljs-comment\"># If running in Docker<\/span>\ndocker logs -f caddy-container\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Track Rate Limit Headers<\/h3>\n<p class=\" text-lg my-6\">Caddy doesn&#8217;t include rate limit headers by default, but you can add them:<\/p>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">example.com <span class=\"hljs-punctuation\">{<\/span>\n    header <span class=\"hljs-punctuation\">{<\/span>\n        X-RateLimit-Limit <span class=\"hljs-string\">\"100\"<\/span>\n        X-RateLimit-Remaining <span class=\"hljs-string\">\"{http.vars.rate_limit_remaining}\"<\/span>\n        X-RateLimit-Reset <span class=\"hljs-string\">\"{http.vars.rate_limit_reset}\"<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    rate_limit <span class=\"hljs-punctuation\">{<\/span>\n        zone api <span class=\"hljs-punctuation\">{<\/span>\n            key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n            events <span class=\"hljs-number\">100<\/span>\n            window <span class=\"hljs-number\">1<\/span>m\n        <span class=\"hljs-punctuation\">}<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n<span class=\"hljs-punctuation\">}<\/span>\n<\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<p class=\" text-lg my-6\">Clients can then check remaining requests before hitting the limit.<\/p>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Complete Production-Ready Examples<\/h2>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Full-Featured E-Commerce Setup<\/h3>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">shop.example.com <span class=\"hljs-punctuation\">{<\/span>\n    # Aggressive rate limit on login (prevent credential stuffing)\n    handle_path \/login <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone login <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">10<\/span>\n                window <span class=\"hljs-number\">1<\/span>m\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Strict on password reset (prevent enumeration)\n    handle_path \/api\/auth\/password-reset <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone password_reset <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">5<\/span>\n                window <span class=\"hljs-number\">1<\/span>h\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Moderate on checkout (prevent fraud)\n    handle_path \/api\/checkout <span class=\"hljs-punctuation\">{<\/span>\n        rate_limit <span class=\"hljs-punctuation\">{<\/span>\n            zone checkout <span class=\"hljs-punctuation\">{<\/span>\n                key <span class=\"hljs-punctuation\">{<\/span>remote_host<span class=\"hljs-punctuation\">}<\/span>\n                events <span class=\"hljs-number\">20<\/span>\n                window <span class=\"hljs-number\">1<\/span>h\n            <span class=\"hljs-punctuation\">}<\/span>\n        <span class=\"hljs-punctuation\">}<\/span>\n        reverse_proxy localhost<span class=\"hljs-punctuation\">:<\/span><span class=\"hljs-number\">3000<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Reasonable API limit (prevent scraping)\n    handle_path \/api<span class=\"hljs-comment\">\/* {\n        rate_limit {\n            zone api {\n                key {remote_host}\n                events 500\n                window 1m\n            }\n        }\n        reverse_proxy localhost:3000\n    }\n\n    # Browsing unrestricted\n    handle {\n        reverse_proxy localhost:3000\n    }\n}\n<\/span><\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<h3 class=\"text-2xl mt-10 mb-4 font-bold \">Tiered API Service<\/h3>\n<div class=\"relative group\">\n<pre class=\"relative bg-[#1a1a1a] border border-gray-700 rounded-lg overflow-x-auto my-8 p-6\"><code class=\"hljs language-json whitespace-pre-wrap break-words text-gray-300\">api.example.com <span class=\"hljs-punctuation\">{<\/span>\n    # Block known abusers first\n    @attackers <span class=\"hljs-punctuation\">{<\/span>\n        remote_ip <span class=\"hljs-number\">192.0<\/span><span class=\"hljs-number\">.2<\/span><span class=\"hljs-number\">.0<\/span>\/<span class=\"hljs-number\">24<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    handle @attackers <span class=\"hljs-punctuation\">{<\/span>\n        respond <span class=\"hljs-string\">\"Access denied\"<\/span> <span class=\"hljs-number\">403<\/span>\n    <span class=\"hljs-punctuation\">}<\/span>\n\n    # Unauthenticated public API (strict)\n    handle_path \/api\/v1\/public<span class=\"hljs-comment\">\/* {\n        rate_limit {\n            zone public {\n                key {remote_host}\n                events 100\n                window 1m\n            }\n        }\n        reverse_proxy localhost:3001\n    }\n\n    # Authenticated API (generous)\n    handle_path \/api\/v1\/* {\n        rate_limit {\n            zone authenticated {\n                key {http.request.header.X-API-Key}\n                events 5000\n                window 1m\n            }\n        }\n        reverse_proxy localhost:3001\n    }\n\n    # Admin endpoints (no limit, but must authenticate)\n    handle_path \/api\/admin\/* {\n        @admin {\n            header X-User-Role admin\n        }\n\n        handle @admin {\n            reverse_proxy localhost:3002\n        }\n\n        respond \"Admin access required\" 401\n    }\n\n    respond \"Not found\" 404\n}\n<\/span><\/code><\/pre>\n<p><button class=\"absolute top-4 cursor-pointer right-4 p-2 rounded-md bg-[#24292e] hover:bg-gray-700 border border-gray-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200\" title=\"Copy code\"><\/button><\/div>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Key Takeaways<\/h2>\n<ol class=\"list-decimal ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Rate limiting is essential<\/strong> for preventing brute-force attacks, DDoS, and accidental abuse.<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Protect sensitive endpoints<\/strong> (login, password reset, API) more aggressively than public routes.<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Understand the difference between keys:<\/strong><\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><code class=\"break-words rounded bg-[#24292E] px-2 py-1 text-[#EEEEEE]\">remote_host<\/code> (IP address) &#8211; Simple but breaks behind proxies<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">API tokens &#8211; Better for identifying individual users<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">Session cookies &#8211; Good for web apps with user accounts<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Test before deploying<\/strong> to avoid blocking legitimate traffic.<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Use appropriate time windows:<\/strong><\/p>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">10-30 seconds for burst limits<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">1 minute for API rate limits<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\">1 hour for sensitive operations like password reset<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Handle proxies correctly<\/strong> &#8211; Use X-Forwarded-For or provider-specific headers.<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Monitor rate limit behavior<\/strong> via logs to identify legitimate issues vs. actual attacks.<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Be generous on legitimate routes<\/strong> &#8211; Only be strict on endpoints that are attack targets.<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Combine with other security<\/strong> &#8211; Rate limiting alone isn&#8217;t enough; pair with authentication, input validation, and IP filtering.<\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><strong>Document your limits<\/strong> &#8211; Keep comments explaining why each limit is set to its value.<\/p>\n<\/li>\n<\/ol>\n<hr \/>\n<h2 class=\"text-3xl font-semibold mt-14 mb-8 \">Further Reading<\/h2>\n<ul class=\"list-disc ml-6 my-6\">\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><a class=\"! !underline\" href=\"https:\/\/caddyserver.com\/docs\/caddyfile\/directives\/rate_limit\" target=\"_blank\" rel=\"noopener noreferrer\">Caddy Documentation &#8211; Rate Limit<\/a><\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><a class=\"! !underline\" href=\"https:\/\/cheatsheetseries.owasp.org\/cheatsheets\/Authentication_Cheat_Sheet.html\" target=\"_blank\" rel=\"noopener noreferrer\">OWASP Brute Force Attack Prevention<\/a><\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><a class=\"! !underline\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Status\/429\" target=\"_blank\" rel=\"noopener noreferrer\">HTTP Status Code 429 (Too Many Requests)<\/a><\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><a class=\"! !underline\" href=\"https:\/\/cloud.google.com\/architecture\/rate-limiting-strategies-techniques\" target=\"_blank\" rel=\"noopener noreferrer\">Rate Limiting Best Practices<\/a><\/p>\n<\/li>\n<li class=\" text-lg my-2\">\n<p class=\" text-lg my-6\"><a class=\"! !underline\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/X-Forwarded-For\" target=\"_blank\" rel=\"noopener noreferrer\">X-Forwarded-For Header Security<\/a><\/p>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction: What is Rate Limiting and Why You Need It Imagine you run a popular website. One day, you notice your server is slowing down dramatically. Traffic is normal, but something&#8217;s wrong. Investigation reveals that one bot is making 10,000 requests per second to your login page, trying to guess user passwords. Or perhaps a&#8230;<\/p>\n","protected":false},"author":1,"featured_media":4738,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[212,236],"tags":[220],"class_list":["post-4914","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops-infrastructure","category-digital-transformation","tag-web","th-blog blog-single has-post-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/posts\/4914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/comments?post=4914"}],"version-history":[{"count":2,"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/posts\/4914\/revisions"}],"predecessor-version":[{"id":4917,"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/posts\/4914\/revisions\/4917"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/media\/4738"}],"wp:attachment":[{"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/media?parent=4914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/categories?post=4914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.softcolon.com\/blogs\/wp-json\/wp\/v2\/tags?post=4914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}