Durable Objects Dynamic Workers 上限變 10:並行呼叫怎麼計算
Durable Objects 裡使用 Dynamic Workers 做 fan-out 時,很容易把兩個不同的數字混在一起:一般 Worker request 的 Dynamic Workers 上限仍是 4,而 Durable Object 同時處理請求時,最多可以涉及 10 個不同的 Dynamic Workers。這不是把每個請求的配額乘大,也不是每個 Object 都能無限平行載入。
直接判斷方式是:看同一個 Durable Object 在這段並行工作中碰到幾個不同的 Dynamic Worker。 同一個 Worker 被呼叫多次,在這個上限的計算上仍只算一個;不同 Worker 才會增加計數。
10 個上限到底怎麼算?
假設一個 Durable Object 同時發起 Dynamic Workers 呼叫,可以用這些情境理解:
| 並行呼叫 | 不同 Worker 數 | 是否超過 Durable Object 上限 |
|---|---|---|
| A 呼叫 8 次 | 1 | 否;同一個 Worker 重複出現只算 1 個 |
| A、B、C、D、E、F | 6 | 否 |
| A 到 J,各 1 次 | 10 | 否;剛好到目前上限 |
| A 到 K,各 1 次 | 11 | 是;需要重用、分批或重新設計 fan-out |
這個規則特別容易在 Promise.all() 中被忽略:陣列長度代表請求數,不代表不同 Worker 數。若陣列裡的每個工作都透過不同的 loader 名稱或入口,才會快速吃掉 10 個 distinct Worker 的上限。
Cloudflare 在 2026 年 8 月 28 日把 Durable Objects 的 Dynamic Workers 限制從 4 提高到 10。官方限制表仍把一般 Worker request 列為 4;所以先確認呼叫者是不是 Durable Object,再套用正確的數字。
為什麼 Durable Object 的數字比較大?
同一個 Durable Object 的並行請求會共用一個 I/O context。Dynamic Workers 文件把這個 context 的限制拆開列出:對 Durable Object,並行請求最多涉及 10 個不同的 Dynamic Workers;對一般 Worker request,則是 4 個。它描述的是執行環境的同時使用邊界,不等於 CPU、記憶體、外部 API 或成本的保證。
也要注意「同一個 Object」這個範圍。不同 Object instance 各自處理自己的請求與狀態;把工作分散出去可能改變可用的並行空間,但也會改變狀態一致性、路由和排程模型。不能只為了繞過數字,就把原本必須序列化的工作切到另一個 Object。
先定位是哪一層把 Worker 數推高
排查時先找出 Dynamic Workers 的載入點,再把「不同 loader/入口」與「實際同時執行的 promise」對起來。例如在專案內先搜尋常見模式:
rg -n 'LOADER\.get|\.load\(|getEntrypoint|Promise\.all' src這個搜尋不是 Cloudflare 專用的診斷指令,而是用來快速建立 inventory。接著逐一確認:
Promise.all()是否同時展開了超過 10 個不同的 Worker 名稱。- 同一個 Worker 是否因為動態組合名稱而被意外拆成多個入口。
- 某些呼叫是否可以在同一個 Dynamic Worker 內依參數處理,而不需要新增入口。
- 失敗發生在 Durable Object 內,還是發生在外層 Worker 呼叫 Durable Object 之前。
- 這段 fan-out 是否還受到外部 API 速率限制或 Durable Object 自身狀態鎖的影響。
在 log 中記錄工作批次、Worker 的邏輯名稱和同一批次的 distinct count,比只記錄「已呼叫幾次」更有用。不要把 secret、完整使用者資料或未必要的 payload 寫進診斷 log。
超過上限時的三種調整方向
1. 把工作分批執行
如果每個 Worker 都必須保留獨立入口,可以把 11 個以上的工作切成數批,每批不超過可用的 distinct Worker 數。每批之間要處理部分失敗、重試與 idempotency,否則只是把一次可見的錯誤改成難以追蹤的半完成狀態。
2. 在語意允許時重用 Worker
若不同工作只是輸入資料不同、執行邏輯相同,考慮讓同一個 Dynamic Worker 接受明確的參數,減少入口數。這會讓 Worker 內的授權、輸入驗證和錯誤隔離更重要;重用不是把不相關的權限硬塞進同一個入口。
3. 重新檢查 Object 邊界
當工作確實屬於不同的狀態分割,才考慮由不同 Durable Object instance 負責。這需要重新確認哪一份資料必須在同一個 Object 內排序、鎖定或交易式更新。若只是批次工作,佇列或明確的工作分派也可能比一次 Promise.all() 更容易操作。
Cloudflare 的 Durable Objects Deployments 分頁適合檢查版本與實際運行指標,但它不會替你推導 distinct Dynamic Workers 的語意。部署版本、錯誤率和 fan-out 計數要一起看,才能判斷是新版本造成入口增加,還是請求模型本來就超過上限。
不要把 10 當成效能承諾
上限提高只表示 Durable Object 可以處理更大的 Dynamic Workers 並行範圍。實際吞吐量仍可能受 Dynamic Worker 執行時間、外部 I/O、Object 狀態競爭、請求大小和失敗重試影響。若你把批次從 4 個放大到 10 個,應重新測量 p95 latency、錯誤率與下游服務的壓力,而不是直接把 concurrency 常數改成 10。
最後可以用一個簡單規則自我檢查:先數「不同 Worker」,再數「同一 Worker 的請求」,最後才決定要重用或分批。這三個數字分開記錄,通常就能解開看似隨機的 Dynamic Workers 限制錯誤。
常見問題
Durable Object 的上限現在是 10 還是 4?
若是同一個 Durable Object 的 Dynamic Workers 並行限制,目前是 10 個不同 Worker;一般 Worker request 的限制仍是 4。先確認執行上下文,不要只看呼叫 API 的程式碼。
同一個 Worker 呼叫 20 次會直接超過 10 嗎?
不會因為這個 distinct Worker 限制直接算成 20 個;同一個 Worker 的多次並行呼叫在該限制上算一個。不過請求數仍可能造成其他資源、下游服務或應用程式邏輯的壓力。
把呼叫移到另一個 Durable Object 就一定能解決嗎?
不一定。這可能改變狀態一致性、路由和失敗恢復方式。只有在工作邊界本來就允許分割時,才應把它當成設計選項。
參考資料:
Cloudflare Dynamic Workers limits
回報錯字、失效連結,或告訴我你想看的延伸主題。