فرض کنید API فروشگاهتان ناگهان با هزاران درخواست در دقیقه روبهرو میشود؛ بخشی از کاربران واقعیاند، بخشی بات، و بخشی هم اسکریپتهایی که میخواهند موجودی یا قیمت را بیوقفه بکشند. بدون کنترل، سرور داغ میکند، دیتابیس قفل میشود و تجربه بقیه کاربران خراب میشود. اینجاست که Rate Limiting وارد میشود؛ سیاستی ساده و قدرتمند که مشخص میکند هر کلاینت در یک بازه زمانی چند درخواست میتواند بفرستد.
در این راهنما به زبان ساده یاد میگیرید Rate Limiting چیست، چرا برای API، لاگین و سرویسهای ابری حیاتی است، الگوریتمهای رایجش کداماند، چطور در Nginx، اپلیکیشن و API Gateway پیادهاش کنید، و در نهایت با چند اشتباه رایج و FAQ جمعبندی میکنیم. اگر سرویستان روی سرور یا زیرساخت ابری اجرا میشود، همین الان این لایه را جدی بگیرید.

Rate Limiting چیست؟
Rate Limiting (محدودسازی نرخ درخواست) مکانیزمی است که تعداد درخواستهای مجاز یک کاربر، IP، توکن API یا هر شناسه دیگر را در واحد زمان محدود میکند. مثلاً «هر IP حداکثر ۶۰ درخواست در دقیقه» یا «هر کلید API حداکثر ۱۰۰۰ درخواست در ساعت».
وقتی سقف پر شود، معمولاً پاسخ HTTP 429 Too Many Requests برمیگردد و گاهی هدرهایی مثل Retry-After یا X-RateLimit-Remaining هم همراهش میآید تا کلاینت بداند کی دوباره تلاش کند.
هدف فقط «بستن راه مهاجم» نیست؛ Rate Limiting به شما کمک میکند منابع سرور را عادلانه بین کاربران تقسیم کنید، از هزینههای ناگهانی کلود جلوگیری کنید و پایداری سرویس را بالا ببرید.
چرا به Rate Limiting نیاز دارید؟
تقریباً هر سرویسی که به اینترنت باز است، دیر یا زود با یکی از این سناریوها روبهرو میشود:
- سوءاستفاده و اسکرابینگ: باتها محتوا، قیمت یا موجودی را بیوقفه میکشند
- حملات Brute-force روی لاگین: حدس زدن رمز با هزاران تلاش پشتسرهم
- DDoS لایهکاربردی (L7): سیل درخواستهای بهظاهر معتبر به endpointهای سنگین
- باگ کلاینت یا Retry بینهایت: یک موبایلاپ خراب میتواند سرور را از پا دربیاورد
- هزینه APIهای پولی: اگر به سرویس ثالث وصلید، بدون سقف، صورتحساب منفجر میشود
با یک سیاست Rate Limiting درست، این ریسکها را قبل از اینکه به outage تبدیل شوند مهار میکنید.
مفاهیم پایه: Window، Quota و Identity
قبل از انتخاب الگوریتم، سه مفهوم را روشن کنید:
| مفهوم | معنی ساده | مثال |
|---|---|---|
| Identity (شناسه) | چه کسی محدود میشود؟ | IP، User ID، API Key، ترکیبی از آنها |
| Quota (سهمیه) | چند درخواست مجاز است؟ | 100 درخواست |
| Window (بازه) | در چه مدت؟ | در ۱ دقیقه / ۱ ساعت / ۱ روز |
| Scope | روی کدام مسیر؟ | کل API، فقط /login، فقط آپلود |
نکته عملی: یک سقف سراسری کافی نیست. معمولاً برای مسیرهای حساس مثل لاگین، OTP و پرداخت، محدودیت سختگیرانهتری میگذارید.
الگوریتمهای رایج Rate Limiting
چهار الگوی پرکاربرد را تقریباً همه جا میبینید. هرکدام تعادل متفاوتی بین سادگی، دقت و تحمل burst دارند.

| الگوریتم | ایده اصلی | مزیت | نقطه ضعف |
|---|---|---|---|
| Fixed Window | شمارنده در یک بازه ثابت (مثلاً هر دقیقه از ثانیه ۰) | پیادهسازی خیلی ساده | در مرز پنجرهها ممکن است burst دوبرابر شود |
| Sliding Window | بازه بهصورت لغزان روی زمان حرکت میکند | دقیقتر از Fixed Window | کمی پیچیدهتر / حافظه بیشتر |
| Token Bucket | توکنها با نرخ ثابت پر میشوند؛ هر درخواست یک توکن مصرف میکند | اجازه burst کنترلشده | تنظیم ظرفیت سطل مهم است |
| Leaky Bucket | درخواستها مثل آب با نرخ ثابت خارج میشوند | خروجی خیلی یکنواخت | برای ترافیک ناگهانی کمتر منعطف است |
برای اکثر APIهای عمومی، Token Bucket یا Sliding Window انتخابهای محبوبی هستند؛ برای صف پردازش پسزمینه گاهی Leaky Bucket منطقیتر است.
کجا Rate Limiting را اعمال کنیم؟
میتوانید محدودیت را در چند لایه بگذارید. بهترین نتیجه معمولاً ترکیب لایههاست:
- لبه شبکه / CDN / WAF: فیلتر اولیه روی IP و الگوهای مشکوک
- ریورسپراکسی (Nginx، HAProxy، Caddy): سریع، نزدیک به ورودی ترافیک
- API Gateway: سهمیه بر اساس کلید API، پلن کاربر، مسیر
- خود اپلیکیشن: منطق دقیقتر بر اساس User ID و وضعیت حساب
- دیتابیس / صف: سقف برای عملیات سنگین مثل export یا گزارش
اگر فقط داخل اپ محدودیت بگذارید و جلوی اپ باز باشد، مهاجم هنوز میتواند منابع پراکسی و TLS را درگیر کند. محدودیت لبه + محدودیت اپ، ترکیب بالغتری است.
مثال عملی: Rate Limiting در Nginx
برای شروع سریع روی سرور، Nginx با ماژول limit_req گزینه رایجی است:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
proxy_pass http://app_upstream;
}
}
اینجا هر IP حدود ۱۰ درخواست در ثانیه دارد و تا ۲۰ درخواست burst را با burst تحمل میکند. برای لاگین میتوانید zone جدا با نرخ خیلی پایینتر تعریف کنید.
یادتان باشد: پشت CDN یا لودبالانسر، IP واقعی ممکن است در هدر X-Forwarded-For باشد. فقط وقتی به پروکسی خودتان اعتماد دارید از آن برای identity استفاده کنید؛ وگرنه spoof میشود.
مثال عملی در اپلیکیشن (Idea کلی)
در سطح اپ، معمولاً از Redis بهعنوان شمارنده سریع استفاده میکنید. منطق ساده Fixed Window:
# Pseudocode
key = f"rl:{user_id}:{minute_bucket}"
count = INCR key
if count == 1:
EXPIRE key 60
if count > 100:
return 429, "Too Many Requests"
برای Token Bucket یا Sliding Window هم کتابخانههای آمادهای در Node، Python، Go و PHP وجود دارد. مهم این است که state محدودیت را روی یک store مشترک (مثل Redis) نگه دارید تا بین چند instance اپ ناسازگار نشود.
طراحی سیاست خوب برای API
یک چکلیست کاربردی قبل از انتشار:
- برای مسیرهای عمومی سقف معقول بگذارید (مثلاً خواندن لیست محصولات)
- برای مسیرهای حساس (login، reset password، OTP) سقف خیلی سختتر
- پلنهای مختلف (Free / Pro) سهمیه متفاوت داشته باشند
- پاسخ ۴۲۹ را مستند کنید و هدرهای راهنما برگردانید
- مانیتورینگ: تعداد ۴۲۹، top offenderها، endpointهای پرفشار
- Whitelist برای health-check و IPهای داخلی خودتان
- در مستندات به کلاینت بگویید چطور backoff کند (مثلاً exponential retry)
| نوع مسیر | پیشنهاد شروع | شناسه |
|---|---|---|
| لاگین / OTP | ۵ تا ۱۰ تلاش در ۱۵ دقیقه | IP + شناسه کاربری |
| API عمومی خواندنی | ۶۰ تا ۳۰۰ درخواست در دقیقه | IP یا API Key |
| API نوشتنی / آپلود | ۱۰ تا ۶۰ درخواست در دقیقه | User ID |
| Webhooks خروجی شما | با صف و retry کنترلشده | مقصد / رویداد |
این اعداد نقطه شروعاند؛ با متریک واقعی ترافیک خودتان تنظیمشان کنید.
Rate Limiting و تجربه کاربری
محدودیت بد طراحیشده میتواند کاربر واقعی را عصبانی کند. چند نکته UX:
- پیام خطای واضح بدهید؛ نه فقط یک ۴۲۹ خالی
- زمان انتظار تقریبی را بگویید (
Retry-After) - در پنل کاربری، باقیمانده سهمیه API را نشان دهید
- برای اپ موبایل، صف و debounce سمت کلاینت بگذارید تا بیخودی به سقف نخورد
هدف «بستن همه» نیست؛ هدف «عبور ترافیک سالم و مهار ترافیک ناسالم» است.
نقش Rate Limiting در امنیت سرور و کلود
Rate Limiting جای WAF، فایروال و احراز هویت را نمیگیرد، ولی لایه دفاعی ارزان و مؤثری است. در کنار HTTPS، بکاپ، پچ منظم و مانیتورینگ، بخشی از بهداشت عملیاتی سرویس شماست.
اگر چند سرویس را روی سرور یا پلتفرم ابری اجرا میکنید، محدودیت نرخ را از همان روز اول در پراکسی یا Gateway فعال کنید؛ هزینهاش کم است و روز حمله یا باگ کلاینت، تفاوتش را میبینید. در زیرساختهایی مثل چابکان میتوانید روی استقرار اپ، شبکه و مقیاسپذیری تمرکز کنید و سیاست Rate Limiting را بهعنوان بخشی از سختکردن سرویس کنارشان داشته باشید.
اشتباهات رایج
- فقط محدود کردن بر اساس IP پشت CDN: بدون استخراج درست IP کلاینت، یا همه یکی میشوند یا spoof میپذیرید.
- یک سقف برای همه endpointها: لاگین و دریافت لیست محصولات نباید سهمیه یکسان داشته باشند.
- نداشتن state مشترک بین چند سرور: هر instance جداگانه میشمارد و سقف واقعی چندبرابر میشود.
- ساکت برگرداندن ۴۲۹: بدون هدر و مستند، کلاینتهای خوب هم گیج میشوند.
- فراموش کردن رباتهای خودی: مانیتورینگ و health-check را از محدودیت مستثنی کنید.
- اتکا فقط به Rate Limiting برای امنیت: همچنان به auth قوی، Captcha در جاهای حساس و WAF نیاز دارید.
جمعبندی
Rate Limiting یعنی سهمیه مشخص برای درخواستها در واحد زمان. با انتخاب درست شناسه، الگوریتم و لایه اجرا، از API و سرورتان در برابر سوءاستفاده، باگ کلاینت و فشار ناگهانی محافظت میکنید؛ بدون اینکه کاربر واقعی را از سرویس محروم کنید.
از یک محدودیت ساده روی Nginx یا Redis شروع کنید، مسیرهای حساس را جداگانه سخت کنید، ۴۲۹ را درست مستند کنید و متریکها را زیر نظر بگیرید. بعد اگر سرویستان رشد کرد، همین سیاست را در API Gateway یا لبه شبکه کاملتر کنید.
اگر بهتازگی میخواهید API یا اپ خود را روی زیرساخت پایدار بالا بیاورید، یک سرور ابری با منابع شفاف، دسترسی مناسب و امکاناتی مثل SSL و مانیتورینگ کمک میکند تمرکزتان روی منطق کسبوکار و سیاستهایی مثل Rate Limiting بماند؛ نه درگیری تماموقت با زیرساخت خام.
سؤالات متداول (FAQ)
تفاوت Rate Limiting و Throttling چیست؟
در عمل خیلی نزدیکاند. معمولاً Rate Limiting به «سقف سخت» و رد کردن درخواست اضافی گفته میشود؛ Throttling بیشتر به کند کردن یا صفکردن ترافیک اشاره دارد. در مستندات محصولات گاهی بهجای هم به کار میروند.
کد وضعیت درست برای محدودیت نرخ چیست؟
استاندارد رایج 429 Too Many Requests است. بهتر است همراهش Retry-After یا هدرهای X-RateLimit-* بفرستید.
آیا Rate Limiting جلوی DDoS را کامل میگیرد؟
برای حملات لایهکاربردی و سوءاستفاده از API کمک بزرگی است، اما حملات حجیم لایهشبکه نیاز به حفاظت L3/L4، CDN و ظرفیت Upstream دارند. Rate Limiting یک لایه است، نه کل دفاع.
Fixed Window بهتر است یا Token Bucket؟
اگر سادگی میخواهید Fixed Window کافی است. اگر میخواهید burst کوتاه مجاز باشد و بعد به نرخ ثابت برگردید، Token Bucket معمولاً بهتر است.
روی چند سرور چطور محدودیت یکسان داشته باشم؟
شمارندهها را در یک store مرکزی مثل Redis نگه دارید، یا محدودیت را روی لایه ورودی مشترک (لودبالانسر / API Gateway) اعمال کنید.
برای گرافکیال یا WebSocket هم لازم است؟
بله. در GraphQL حتی یک query پیچیده میتواند معادل دهها درخواست باشد؛ بهتر است علاوه بر تعداد درخواست، پیچیدگی/هزینه را هم محدود کنید. در WebSocket هم نرخ پیام و اندازه فریم را کنترل کنید.