Rate Limiting: איך מגנים API מעומס יתר ומניצול לרעה

מאת צוות מדיה דיל · 31.08.2026 · אבטחת מידע · 7 דק׳ קריאה

Rate Limiting מגביל את מספר הבקשות שמשתמש או שירות יכולים לשלוח בפרק זמן נתון. הנה האלגוריתמים המרכזיים ומתי כל אחד מתאים.

בלי הגבלה, לקוח יחיד — בין אם בטעות (באג בלולאה) ובין אם בזדון (תקיפה) — יכול לשלוח אלפי בקשות בשנייה ולהעמיס על שרת שאמור לשרת אלפי משתמשים אחרים. Rate Limiting קובע תקרה ברורה: כמה בקשות מותרות לכל משתמש או שירות בפרק זמן נתון.

Fixed Window: הגישה הפשוטה ביותר

סופרים בקשות בחלון זמן קבוע (למשל כל דקה מתחילה בשעה עגולה), וחוסמים כשהמספר חוצה סף. פשוט להטמעה, אבל סובל מבעיית "קצה": משתמש יכול לשלוח את מלוא המכסה בסוף חלון אחד ומיד שוב בתחילת החלון הבא, ולמעשה לעקוף את ההגבלה לרגע קצר.

Sliding Window: פתרון מדויק יותר

במקום חלונות קבועים, סופרים בקשות בטווח הזמן הנע האחרון (למשל "60 השניות האחרונות", לא "הדקה העגולה הנוכחית"). מדויק יותר מ-Fixed Window אבל דורש יותר זיכרון וחישוב, כי צריך לזכור את חותמות הזמן של הבקשות האחרונות, לא רק מונה בודד.

Token Bucket: הגישה הגמישה ביותר

כל משתמש מקבל "דלי" עם מספר טוקנים מוגבל, שמתמלא מחדש בקצב קבוע. כל בקשה צורכת טוקן; כשהדלי ריק, בקשות נדחות. היתרון: מאפשר פרצי בקשות קצרים (Burst) כל עוד יש טוקנים זמינים בדלי, במקום להגביל בקצב אחיד קשיח.

איפה אוכפים את ההגבלה

Rate Limiting יכול לרוץ ברמת ה-API Gateway (לפני שהבקשה בכלל מגיעה לשרת האפליקציה), ברמת האפליקציה עצמה, או בשתיהן. אכיפה מוקדמת ב-Gateway חוסכת משאבי שרת יקרים על בקשות שנדחות בכל מקרה.

הגבלה לפי מה: IP, משתמש, או API Key

הגבלה לפי כתובת IP פשוטה אבל לא מדויקת — כמה משתמשים לגיטימיים יכולים לשתף IP (רשת ארגונית). הגבלה לפי משתמש מזוהה או API Key מדויקת יותר, אבל דורשת שהבקשה כבר עברה שלב אימות לפני שההגבלה נאכפת.

429 Too Many Requests: תגובה נכונה ללקוח

כשבקשה נדחית בגלל חריגה מהמכסה, השרת צריך להחזיר קוד סטטוס 429 ברור, ואופציונלית כותרת Retry-After שאומרת ללקוח בדיוק כמה זמן לחכות לפני ניסיון חוזר — לא רק שגיאה גנרית שמשאירה את הלקוח מנחש.

הגנה נוספת מעבר לביצועים

מעבר למניעת עומס, Rate Limiting הוא קו הגנה מרכזי מפני תקיפות Brute Force על מסכי התחברות ו-Credential Stuffing. הגבלה קפדנית במיוחד על נקודות קצה רגישות, בדיוק כמו העקרונות שהרחבנו עליהם במאמר על Zero Trust Architecture, מקטינה דרמטית את משטח התקיפה.

Rate Limiting מבוזר בין כמה שרתים

כשהאפליקציה רצה על כמה שרתים במקביל, מונה בקשות מקומי לכל שרת לא מספיק — משתמש יכול לפזר בקשות בין שרתים ולעקוף את ההגבלה. פתרון מרכזי כמו Redis, ששומר את המונה במקום משותף לכל השרתים, הכרחי בסביבה מבוזרת.

הגבלות שונות לרמות שירות שונות

מוצרי SaaS רבים מגדירים מכסות שונות ללקוחות בתוכניות שונות — לקוח בתוכנית בסיסית מקבל מכסת בקשות נמוכה יותר מלקוח בתוכנית פרימיום. הטמעה גמישה של Rate Limiting לפי תוכנית, לא רק גבול אחיד לכולם, היא לרוב חלק מהמודל העסקי עצמו.

ה-API שלכם חשוף לעומס יתר או לניצול לרעה? וואטסאפ.

Rate Limiting ב-GraphQL: לא רק ספירת בקשות

ב-API מסוג REST, ספירת בקשות פשוטה עובדת סביר, כי כל בקשה בערך שקולה בעלות עיבוד עבור השרת. ב-GraphQL בקשה בודדת יכולה להכיל שאילתה מקוננת עם כמה רמות של קשרים בין ישויות, שמייצרת עומס עצום על מסד הנתונים והשרת, בעוד בקשה אחרת פשוטה וקלה מאוד לעיבוד — כך שספירת בקשות גרידא לא מגנה מספיק מפני עומס אמיתי. גישה נפוצה יותר ב-GraphQL היא הגבלה לפי "עלות" מחושבת של השאילתה — מספר השדות, עומק הקינון, וגודל התוצאה הצפוי — ולא לפי מספר הבקשות בלבד, כך שלקוח לא יכול לעקוף את ההגנה פשוט על ידי אריזת עומס כבד בבקשה בודדת.

איך לקוח צריך להתמודד עם תגובת 429

הגנה טובה בצד השרת היא רק חצי מהתמונה — לקוח (אפליקציית מובייל, Frontend, שירות אחר) שמקבל 429 ופשוט מנסה שוב מיד יוצר עומס נוסף בדיוק כשהשרת כבר עמוס, ועלול להחמיר את המצב במקום לפתור אותו. הגישה הנכונה היא Exponential Backoff: לחכות זמן הולך וגדל בין ניסיונות חוזרים, תוך כיבוד כותרת Retry-After כשהיא קיימת בתגובה, במקום להציף את השרת בבקשות חוזרות ונשנות בקצב קבוע. שירותים שמבצעים אינטגרציה בין מערכות (Server-to-Server) צריכים גם תור פנימי (Queue) שסופג את הבקשות שנדחו ומנסה שוב בקצב מבוקר, במקום לאבד אותן לגמרי כשהמכסה חורגת לרגע.

שירותי Rate Limiting מנוהלים מול הטמעה עצמאית

שירותים כמו Cloudflare או API Gateway מנוהל מציעים הגבלת קצב מובנית ברמת הרשת, עוד לפני שהבקשה מגיעה לתשתית שלכם בכלל — יתרון משמעותי מבחינת עומס וגם מבחינת הגנה מפני תעבורה זדונית בקנה מידה גדול, כי החסימה קורית קרוב יותר למקור התעבורה. הטמעה עצמאית באפליקציה נותנת שליטה מדויקת יותר על לוגיקת ההגבלה לפי הקשר עסקי — למשל תוכנית מנוי, סוג פעולה, או מזהה לקוח ספציפי — אך דורשת תחזוקה ומשאבים משלכם, כולל תשתית משותפת כמו Redis לתיאום בין שרתים. השילוב הנפוץ בפועל הוא הגנה בסיסית ברמת הרשת מפני עומס גס, ולוגיקה עדינה יותר ברמת האפליקציה למכסות עסקיות מדויקות.

הגבלה גלובלית מול הגבלה פר-נקודת-קצה

מכסה גלובלית אחת למשתמש (למשל אלף בקשות בשעה, לכל סוגי הבקשות יחד) לא מבחינה בין נקודת קצה קלה לעיבוד לבין נקודת קצה כבדה שדורשת חישוב יקר או פנייה למסד נתונים מורכבת. גישה מדויקת יותר מגדירה מכסות נפרדות לפי נקודת קצה — הגבלה מחמירה יותר על פעולות יקרות (כמו ייצוא דוח גדול או חיפוש מורכב), והגבלה נדיבה יותר על פעולות קלות (כמו בדיקת סטטוס). כך המשאב היקר באמת מוגן ספציפית, בלי להגביל בצורה גורפת ולא נחוצה גם פעולות זולות שלא מסכנות את השרת.

תיעוד המכסה ללקוחות API חיצוניים

כשה-API משמש מפתחים חיצוניים ולא רק את האפליקציה הפנימית שלכם, חשוב לחשוף להם את מצב המכסה בכותרות תגובה סטנדרטיות — כמו כמות הבקשות שנותרו וזמן האיפוס הבא — כך שהם יכולים להתאים את קצב הפנייה שלהם מראש, במקום לגלות את ההגבלה רק כשהם כבר נחסמים. תיעוד ברור של המכסות בדוקומנטציה הרשמית של ה-API, כולל דוגמאות לטיפול בתגובת 429, חוסך פניות תמיכה חוזרות ונשנות ממפתחים שמתקשים להבין למה הבקשות שלהם נדחות.

בדיקת ה-Rate Limiting עצמו לפני עלייה לאוויר

הגבלת קצב שלא נבדקה תחת עומס אמיתי עלולה להתגלות כשגויה בדיוק ברגע שהיא הכי נחוצה — למשל אכיפה לא עקבית כשכמה בקשות מגיעות ממש באותה מילישנייה, או מונה שמתאפס לא נכון בגבול בין חלונות זמן. בדיקת עומס ייעודית שמדמה חריגה ממכסה במכוון, ובודקת שהתגובה (429, Retry-After, אי-חסימת משתמשים תקינים) אכן מתנהגת כמצופה, חוסכת גילוי כואב שהמנגנון לא עבד כמו שחשבו רק כשכבר יש בעיה בפרודקשן.

כן, לרוב מומלץ — גם שירות פנימי יכול להכיל באג שיוצר לולאה של קריאות מיותרות, ובלי הגבלה גם על תעבורה פנימית, הוא עלול להעמיס על המערכת בדיוק כמו לקוח חיצוני. אפשר להגדיר לשירותים פנימיים מכסה נדיבה יותר משירותים חיצוניים, אך לא לוותר על הגבלה לחלוטין רק כי מדובר ב"תעבורה שלנו".

שאלות נפוצות

מה ההבדל בין Rate Limiting ל-Throttling?

המונחים משמשים לעיתים לסירוגין, אך ההבדל המקובל הוא ש-Rate Limiting דוחה בקשות שחורגות מהמכסה ומחזיר שגיאה ללקוח, בעוד Throttling מעכב אותן ומעבד אותן בקצב מוגבל במקום לדחות לגמרי. שתי הגישות משמשות להגנה מפני עומס יתר, אך ההתנהגות שהלקוח חווה שונה מהותית — דחייה מיידית מול המתנה ארוכה יותר לתגובה.

האם Rate Limiting מספיק כהגנה מפני מתקפת DDoS?

לא לבדו. Rate Limiting מגן היטב מפני שימוש חריג מלקוח בודד או מתקפות ברמת אפליקציה כמו Brute Force על מסך התחברות, אבל מתקפת DDoS מבוזרת אמיתית מגיעה מאלפי מקורות שונים במקביל, כל אחד מתחת לסף ההגבלה הבודד, ודורשת הגנה נוספת ברמת הרשת ותשתית ייעודית לספיגת נפח תעבורה עצום שמעורבים בה גורמים חיצוניים.

כמה זמן לוקח להטמיע Rate Limiting בסיסי במערכת קיימת?

הטמעה של אלגוריתם Fixed Window או Token Bucket בסיסי על נקודת קצה בודדת היא עבודה קטנה יחסית שאפשר להשלים במהירות. המורכבות עולה כשצריך לתמוך במכסות שונות לפי תוכנית לקוח, אכיפה מבוזרת בין כמה שרתים באמצעות מאגר משותף, וכיסוי כל נקודות הקצה הרגישות במערכת — זה מה שהופך את הפרויקט המלא לרחב יותר ממה שנראה במבט ראשון.

האם צריך הגבלת קצב גם בצד ה-Frontend?

הגבלה אמיתית שאפשר לסמוך עליה תמיד חייבת לאכוף בצד השרת, כי כל לוגיקה בצד הלקוח ניתנת לעקיפה בקלות על ידי מי שרוצה בכך. עם זאת, הגבלה עדינה גם ב-Frontend — למשל מניעת לחיצות כפולות מהירות על כפתור שליחה — משפרת חוויית משתמש ומצמצמת בקשות מיותרות עוד לפני שהן יוצאות כלל לרשת.

מה עושים כשמשתמשים לגיטימיים נחסמים בטעות?

זה סימן שהמכסה מוגדרת נמוך מדי ביחס לדפוס שימוש תקין, או שההגבלה לא מבחינה נכון בין סוגי משתמשים ופעולות. הפתרון הוא לנטר דחיות 429 בפועל לאורך זמן, לבדוק אילו מהן מגיעות ממשתמשים לגיטימיים ולא מתקיפות, ולכייל את הסף בהתאם לנתונים האמיתיים — לא להוריד את ההגנה לגמרי אלא להתאים אותה בזהירות.

תגיות: Rate Limiting · API Security · Token Bucket · DDoS Protection

← חזרה לבלוג · צור קשר