Rate Limiting ב-SaaS: הגנה על ה-API בלי לפגוע בלקוחות הלגיטימיים
מאת צוות מדיה דיל · 03.08.2026 · SaaS Architecture · 9 דק׳
מדריך טכני ל-Rate Limiting במערכות SaaS - אלגוריתמי token bucket ו-sliding window, הגבלה per-tenant, ותכנון תגובת 429 שלא שוברת אינטגרציות.
API ציבורי בלי rate limiting הוא תאונה שממתינה לקרות. יכול להיות שזה לקוח עם באג בקוד שלו ששולח 10,000 בקשות בשנייה בלי כוונה, ויכול להיות שזה שחקן זדוני שמנסה brute-force על endpoint התחברות. בשני המקרים, בלי הגנה, שירות אחד יכול להפיל את כל התשתית עבור כל הלקוחות האחרים. Rate limiting הוא המנגנון שמגן על המערכת מפני שימוש חריג - אבל תכנון גרוע שלו יכול להזיק לא פחות מהיעדרו לגמרי: לקוחות לגיטימיים שנחסמים בטעות, אינטגרציות B2B שנשברות בגלל מגבלות לא סבירות, וחוויית מפתחים גרועה שמובילה לתלונות ולביטול מנויים.
אלגוריתמים: Fixed Window, Sliding Window ו-Token Bucket
הגישה הפשוטה ביותר, fixed window, סופרת בקשות בחלון זמן קבוע (למשל "עד 100 בקשות בדקה", מתאפס בתחילת כל דקה). הבעיה שלה היא effect של "פרץ בגבול" - לקוח יכול לשלוח 100 בקשות בשנייה האחרונה של דקה אחת, ועוד 100 בשנייה הראשונה של הדקה הבאה - 200 בקשות בשתי שניות, בעוד המגבלה הנומינלית היא 100 לדקה. sliding window log או sliding window counter פותרים את זה על ידי חישוב רציף שמסתכל על חלון זמן נע ולא קפוא, אבל דורשים יותר משאבי חישוב ואחסון (צריך לזכור timestamps של בקשות בודדות, או לפחות אומדן משוקלל בין שני חלונות). Token bucket הוא הגישה הפופולרית ביותר בפועל - כל לקוח מקבל "דלי" עם קיבולת מקסימלית של טוקנים שמתמלא בקצב קבוע; כל בקשה צורכת טוקן, ואם הדלי ריק - הבקשה נדחית. היתרון הגדול של token bucket הוא שהוא מאפשר burst מבוקר (אם הדלי מלא, אפשר לשלוח כמה בקשות ברצף) תוך שמירה על קצב ממוצע ארוך-טווח - התנהגות שמתאימה יותר לדפוסי שימוש אמיתיים מאשר הגבלה קשיחה.
איפה מיישמים: אפליקציה, Gateway, או שכבת רשת
rate limiting אפשר ליישם בכמה שכבות, וכל שכבה מגנה מפני איום שונה. ברמת ה-CDN/edge (כמו Cloudflare) - ההגנה הרחוקה ביותר מהשרת, יעילה נגד התקפות DDoS בקנה מידה גדול לפני שהן בכלל מגיעות לתשתית. ברמת ה-API Gateway - המקום הנפוץ ביותר להטמעת מדיניות rate limiting עסקית (כמה בקשות מותר ללקוח לפי תוכנית המנוי שלו), נדון בהרחבה במדריך שלנו לארכיטקטורת API Gateway. וברמת האפליקציה עצמה - הגבלה עדינה יותר סביב endpoints ספציפיים שרגישים במיוחד (למשל endpoint שליחת SMS שיקר לכל בקשה, או endpoint login שרגיש ל-brute force). ההמלצה המעשית היא הגנה רב-שכבתית: edge לחסימת התקפות גסות, gateway למדיניות עסקית לפי tenant, ואפליקציה להגנות ממוקדות במיוחד רגישות.
הגבלה Per-Tenant לא Per-IP
טעות ארכיטקטונית נפוצה ב-SaaS B2B היא הגבלת קצב לפי כתובת IP - מודל שהתאים לאינטרנט הציבורי הכללי אבל לא ל-SaaS. בעולם ה-B2B, לקוח ארגוני גדול עשוי לשלוח את כל הבקשות שלו מ-IP יחיד (שרתי החברה, או NAT משותף), בעוד לקוחות קטנים רבים משתמשים ב-IP-ים משתנים דרך ספקי ענן. הגישה הנכונה היא הגבלה לפי מפתח API או tenant_id - כל לקוח מקבל מכסת בקשות עצמאית בהתאם לתוכנית המנוי שלו (Free: 100 בקשות לדקה, Pro: 1,000, Enterprise: מותאם אישית), ללא תלות בכתובת ה-IP שממנה הבקשות מגיעות בפועל. זה גם פותר בעיה נוספת - שירותים ש-proxy-ים בקשות דרך שירות ביניים משותף (למשל אינטגרציה דרך Zapier) שהיו נחסמים בטעות אם ההגבלה הייתה לפי IP בלבד.
תגובת 429 שלא שוברת אינטגרציות
כשלקוח חורג ממכסת הבקשות, הסטנדרט המקובל הוא להחזיר HTTP status code 429 (Too Many Requests). אבל תגובה טובה היא הרבה יותר מקוד סטטוס בלבד - היא חייבת לכלול headers שמנחים את הלקוח מה לעשות הלאה: Retry-After (כמה שניות לחכות לפני ניסיון חוזר), ולעיתים X-RateLimit-Limit, X-RateLimit-Remaining ו-X-RateLimit-Reset שמאפשרים ל-SDK לקוח מתוחכם למנוע חריגה מלכתחילה ולא רק להגיב אליה אחרי מעשה. SDK רשמי טוב (שכל ספק API מתקדם מספק) יטמיע retry אוטומטי עם backoff מבוסס Retry-After, כך שמפתחים שמשתמשים ב-SDK הרשמי כמעט לא ייחשפו כלל לשגיאות 429 בזרימת עבודה רגילה. תיעוד ברור של מדיניות ה-rate limiting במסמכי ה-API הוא לא פחות חשוב מהמימוש הטכני עצמו - מפתח שמבין את המגבלות מראש בונה אינטגרציה טובה יותר.
אחסון מונים: Redis כתשתית סטנדרטית
מימוש rate limiting מבוזר (כשיש כמה instances של השרת) דורש מקום מרכזי לספירת בקשות שכל ה-instances רואים באופן עקבי - זיכרון מקומי לכל instance לא מספיק, כי לקוח יכול "לפזר" בקשות בין instances שונים ולעקוף את המגבלה. Redis הוא הבחירה הסטנדרטית לכך, הודות למהירותו הגבוהה ולפקודות אטומיות מובנות (כמו INCR עם EXPIRE) שמתאימות בול למימוש token bucket או sliding window באופן מבוזר ועקבי. ספריות מוכנות כמו rate-limiter-flexible ב-Node.js או django-ratelimit ב-Python מספקות מימושים בדוקים מעל Redis, ועדיף להשתמש בהן על פני מימוש עצמאי - יש כאן הרבה edge cases עדינים (race conditions בספירה בו-זמנית) שקל לפספס.
טעויות נפוצות בפרודקשן
הטעות הראשונה היא הגבלה לפי IP במקום per-tenant, שפוגעת בצורה לא הוגנת בלקוחות ארגוניים. טעות שנייה היא תגובת 429 בלי headers מנחים, שגורמת לאינטגרציות לקוח להתנהג בצורה לא צפויה - חלקן ינסו שוב מיד בלולאה אינסופית, מה שמחמיר את הבעיה. טעות שלישית היא הגבלה אחידה לכל ה-endpoints, כשבפועל endpoint כתיבה כבד (יצירת דוח מורכב) צריך מגבלה שונה לגמרי מ-endpoint קריאה קל (בדיקת סטטוס). טעות רביעית היא חוסר תיאום בין שכבות ההגבלה השונות (edge, gateway, אפליקציה), מה שיוצר חוויה לא עקבית ולעיתים סתירות בין ההגבלות שקשה לדבג.
סיכום
Rate limiting מתוכנן היטב הוא איזון עדין בין הגנה על התשתית לבין חוויית מפתח טובה. token bucket עם הגבלה per-tenant, תגובות 429 עם headers ברורים, ומימוש מבוזר אמין דרך Redis - אלה יחד יוצרים שכבת הגנה שמגינה על המערכת בלי להפוך את השימוש ב-API למסע ייסורים ללקוחות הלגיטימיים. במדיה דיל אנחנו מטמיעים rate limiting כחלק אינטגרלי מכל API ואינטגרציה שאנחנו בונים, כי הוא לרוב ההבדל בין תשתית יציבה תחת עומס לבין נקודת כשל שמפילה הכל.
תגיות: rate limiting · token bucket · API throttling · Redis · 429 status code · SaaS architecture · multi-tenant