你寫了一個程式,每秒呼叫一次 API,一開始都正常;接著把迴圈加快,突然開始收到 429 Too Many Requests。或者你同時開很多 worker,前幾分鐘跑得很順,之後整批 request 一起失敗。這時最直覺的反應常是:「伺服器不是還活著嗎?為什麼不讓我繼續打?」
因為一個服務能處理 request,不代表它應該讓任何一個 client 無限制地消耗資源。Rate limit,就是服務對「某段時間內可以做多少次操作」設下的邊界。
一句話先記住:rate limit 不是單純在擋人,而是在分配有限資源,避免單一來源把整個服務吃光。
Rate Limit 限制的到底是什麼?
最常見的形式是「一段時間內最多幾次 request」,例如每分鐘、每小時或每秒允許一定數量。但實際系統不一定只算 request 次數。它也可能針對某個 endpoint、某個帳號、API key、IP、token、組織,甚至某種特別昂貴的操作分開計算。
所以「這個 API 的 limit 是多少」有時不是一個數字可以回答。登入 endpoint 可能比讀取公開資料更嚴;搜尋可能有自己的限制;寫入資料、生成內容或執行高成本運算,也可能使用另一套 budget。
│
└→ 超過規則:拒絕、延後或要求稍後重試
為什麼服務需要限流?
第一個原因是可用性。如果一個使用者的錯誤迴圈每秒送出幾千次 request,沒有任何限制時,它可能佔滿連線、CPU、database connection 或下游服務容量,最後讓其他正常使用者一起變慢。
第二個原因是防止濫用。登入、驗證碼、搜尋、留言、建立帳號這些 endpoint,都可能被暴力嘗試、爬蟲或自動化程式大量呼叫。Cloudflare 的 rate limiting 文件就把保護登入 endpoint、防止 brute-force,以及限制單一 client 的 API 呼叫列為典型用途。
第三個原因是成本與公平性。某些 request 背後可能會呼叫資料庫、AI 模型、第三方 API 或其他付費資源。如果完全沒有 rate limit,一個 client 不只可能拖慢系統,還可能直接把營運成本拉高。
429 Too Many Requests 是最典型的訊號
HTTP 的 429 Too Many Requests 就是專門用來表示「在一段時間內送了太多 request」的狀態碼。MDN 也指出,response 可以附上 Retry-After header,告訴 client 應該等多久再試。
Retry-After: 60
這裡最重要的是:429 通常不是叫你立刻重送。如果 client 一看到失敗就馬上 retry,而且所有 worker 同時這樣做,反而可能製造更多流量,把原本的問題放大。
Quota 和 Rate Limit 很像,但不是完全同一件事
Rate limit 比較關心「速度」:你在某個時間窗口內送得多快。Quota 比較像「總額」:例如一天能用多少次、每月能處理多少 token、帳號方案總共允許多少用量。
兩者可以同時存在。你可能每月有很大的總額,但仍不能在一秒內把整個月的額度一次打完;也可能每秒限制很寬鬆,但每天仍有總量上限。
Rate limit:控制速度。
Quota:控制總量。
實際產品常同時使用兩者。
固定時間窗不是唯一做法
最容易想像的規則是 fixed window:例如「每分鐘最多 100 次」。但這種做法會遇到邊界問題:某個 client 可以在 12:00:59 打一批 request,到了 12:01:00 窗口重設,又立刻再打一批,瞬間流量仍然可能很高。
因此實際系統也常使用 sliding window、token bucket 或其他方法,讓限制更平滑。你不一定需要先背演算法名稱;真正要理解的是,rate limit 的核心不是計時器本身,而是系統怎麼把「可接受的流量」轉成可以執行的規則。
被限流之後,正確做法不是瘋狂 Retry
如果 server 有回 Retry-After,client 應優先尊重它。如果 API 提供自己的 rate-limit headers,也應讀取剩餘額度與 reset 時間,而不是猜。
當沒有明確等待時間時,常見做法是 backoff:第一次失敗先等一下,下一次再失敗就等更久。GitHub 的 REST API 文件在處理 secondary rate limit 時,也建議持續失敗時使用逐步增加的等待時間,而不是不停重送。
實務上還常加入一點隨機時間,也就是 jitter。原因很簡單:假設 100 個 worker 同時被擋,又都精準等待 60 秒,它們會在第 61 秒一起醒來,再形成另一波尖峰。稍微錯開重試時間,可以避免這種同步碰撞。
↓ 再失敗
等待更久 → retry
↓
達到上限 → 停止並回報錯誤
Rate Limit 不等於「伺服器最多只能做到這麼多」
這是一個很容易混淆的地方。服務設定每分鐘 100 次,不代表第 101 次 request 技術上一定處理不了。限制可能是產品政策、安全策略、成本控制,或為了替所有使用者保留容量。
反過來也一樣:把 limit 設得很高,不代表 backend 就能承受那個流量。真正的容量還會受到 application、database、cache、queue、network 和其他 dependency 影響。Rate limiter 只是在入口多加一道流量控制,它不會自動讓後面的系統變快。
設計 API 時,Rate Limit 應該讓 client 看得懂
好的限流不只是「超過就擋」。client 還需要知道發生了什麼,以及下一步怎麼做。使用適當的 status code、回傳可理解的錯誤訊息、提供 retry 或 reset 資訊,都能讓整合方寫出比較穩定的程式。
同時,限制的 key 也很重要。只用 IP 可能讓同一個校園、公司或 NAT 後面的很多人共用一個額度;只用 account 則要考慮單一帳號被濫用。實際設計通常會根據 endpoint、身份驗證方式和威脅模型決定。
最後,把 Rate Limit 想成流量規則
API 不是一個可以無限吞 request 的黑洞。每一次呼叫背後都有計算、儲存、網路與其他共享資源。Rate limit 的工作,就是在流量進入核心系統之前先訂好規則:誰可以用、多久能用多少、超過之後該怎麼辦。
所以看到 429 時,不要只把它理解成「API 不讓我用」。更準確的理解是:你目前的 request rate 超過了服務允許的節奏,而 client 現在應該減速。
如果只想先留一句:Rate limit 控制的不是你「能不能呼叫 API」,而是你「能多快、用多少資源地呼叫它」。
資料來源
HTTP 429 Too Many Requests 與 Retry-After 的定義參考 MDN Web Docs;primary / secondary rate limit、rate-limit response headers 與 retry 建議參考 GitHub REST API rate limit 文件;以 rate limiting 保護登入 endpoint、API 與防止濫用的用途參考 Cloudflare Rate Limiting Rules。