sell運算
dataset

Durable Objects

一個單一、永遠都在的物件,把程式碼和自己的儲存結合在一起——很適合即時聊天、多人連線,以及任何「大家必須對齊同一份真相」的場景。

1每個名稱一個實例
10 GB每個 SQLite 儲存
每帳號物件數
0ms冷啟動時間
lightbulb

Durable Objects 是什麼?

Durable Object 是一種特別的 Worker,它把「運算(執行程式碼)」和「自己專屬的儲存」獨特地結合在一起。對於同一個名稱,全世界永遠只有「一個」實例(instance),住在同一個地方,所有人都跟它對話。

「Stateful(有狀態)」是指它在請求之間會「記住」事情。一般的 Worker 一做完就忘光光,這叫「stateless(無狀態)」。Durable Object 則會保留它的資料(同時放在記憶體和持久儲存裡),所以下一個請求看得到上一個請求留下的東西。

support_agent

把它想成…

想像每間會議室都配一位專屬櫃檯人員。所有想用那間會議室的人,永遠都去找「同一位」櫃檯,而他把那間會議室的行程記在自己的小本子裡。不會重複預約、不會搞混——一間房、一位真相守門人。

help

為什麼要用它?

讓很多使用者「即時協調」是軟體中最難的問題之一。一般來說你得用資料庫、鎖(lock)、訊息中介來避免大家互相覆蓋。Durable Objects 把這件事變簡單:因為每個名稱只有「一個」實例,它自然就成了唯一的協調點。

person_pin

單一真相來源

每個名稱只有一個實例,就不會有互相衝突的副本,也不用解開競爭條件(race condition)。

memory

內建儲存

每個物件都有自己的 SQLite 資料庫——強一致性又快,不用另外接一個資料庫。

sync_alt

即時協調

可以長時間保持 WebSocket 連線,一次把更新廣播給很多使用者。

bolt

零冷啟動

和 Workers 一樣,它瞬間啟動,並在離使用者最近的邊緣執行。

all_inclusive

靠數量擴充

可以建立無限多個物件——一個聊天室、一份文件、一位使用者各一個——它們會橫向擴充。

schedule

鬧鐘(Alarms)

可以排程讓物件稍後叫醒自己來做事——不需要外部的定時排程。

target

什麼時候該用?

只要有多人或多個請求需要「共享並對齊同一份即時狀態」,就該想到 Durable Objects。

chat

即時聊天室

一個房間一個物件,握著所有連線,並即時把每則新訊息廣播出去。

edit_document

協作編輯

像 Google 文件那樣,很多人同時編輯同一份文件。

sports_esports

多人遊戲

一場遊戲一個物件,為所有玩家保管權威的遊戲狀態。

shopping_cart

購物車與計數器

每位使用者的購物車、或每個資源的計數器,絕不能漏算或重複計算。

speed

流量限制

追蹤使用者打 API 的頻率,從一個一致的地方執行限制。

smart_toy

AI 代理人

讓每個 AI 代理人擁有自己長期存在、跨回合保留的記憶與狀態。

rocket_launch

怎麼開始用?

你把 Durable Object 寫成一個 JavaScript / TypeScript 類別,在 wrangler.jsonc 裡用一個 binding(綁定)和一個 migration(遷移)登記它,然後在一般的 Worker 裡「用名稱查到它」並呼叫它。

  1. 建立 Worker 專案

    從 Hello World 範本開始,再把你的 Durable Object 類別加進程式碼。

    bash
    npm create cloudflare@latest -- my-do-app
    cd my-do-app
  2. 登記物件

    在 wrangler.jsonc 裡加上一個 binding(Worker 用來呼叫它的名稱)和一個 migration(告訴 Cloudflare 這是一個新的、用 SQLite 儲存的類別)。

    jsonc
    {
      "durable_objects": {
        "bindings": [
          { "name": "MY_DURABLE_OBJECT", "class_name": "MyDurableObject" }
        ]
      },
      "migrations": [
        { "tag": "v1", "new_sqlite_classes": ["MyDurableObject"] }
      ]
    }
  3. 部署

    發佈到 Cloudflare 的網路。你請求的每個不同名稱,都會自動拿到屬於自己的實例。

    bash
    npx wrangler deploy
tssrc/index.ts — 一個帶 SQLite 儲存的物件
import { DurableObject } from "cloudflare:workers";

export class MyDurableObject extends DurableObject {
  // Run a query against this object's own private SQLite database
  async sayHello() {
    const row = this.ctx.storage.sql
      .exec("SELECT 'Hello, World!' AS greeting")
      .one();
    return row.greeting;
  }
}

export default {
  async fetch(request, env) {
    // getByName returns the ONE instance for this name (creating it if needed)
    const stub = env.MY_DURABLE_OBJECT.getByName("room-42");
    // Call a method on it directly via RPC
    const greeting = await stub.sayHello();
    return new Response(greeting);
  },
};
key

名稱對應到實例

getByName("room-42") 永遠回傳「同一個」實例。不管在地球哪個角落再用一次 "room-42",你都會連到一模一樣的物件,帶著相同的記憶體和儲存。這就是全部的魔法所在。

school

重點概念

fingerprint

ID / 名稱

一個全球唯一的識別碼,對應到剛好一個實例。相同名稱 = 相同物件。

smart_button

Stub(代理)

一個本地的把手,你在上面呼叫方法;Cloudflare 會把呼叫轉送到真正的物件所在之處。

database

儲存 API

內建在每個物件裡、具交易性與強一致性的 SQLite 儲存。

bedtime

WebSocket 休眠

用很低成本保持成千上萬條連線——物件休眠,但連線依然活著。

alarm

Alarms(鬧鐘)

排程讓物件在未來某個時間叫醒自己做事,例如重試或清理。

move_up

Migration(遷移)

一個小小的設定項目,告訴 Cloudflare 你要新增、改名或移除某個物件類別。

tips_and_updates

小提示與計費

savings

免費試用

用 SQLite 儲存的 Durable Objects 在 Workers 免費方案就能用(限制較低),所以你不用付費就能做一個即時 App、把這套模型學起來。

值得記住的限制

  • 物件數量:每帳號 / 每類別都是無上限
  • 每個物件儲存:付費方案最多 10 GB 的 SQLite
  • 吞吐量:每個物件約 1,000 請求/秒 的軟性上限
  • CPU 時間:預設 30 秒,最多可設定到 5 分鐘
  • SQLite 的鍵 + 值合計:最多 2 MB
balance

一個物件 = 一個瓶頸

因為某個名稱的所有流量都匯集到單一實例,一個超熱門的物件可能變成瓶頸(約 1,000 req/s)。把工作拆給很多物件——例如一個房間或一位使用者各一個——就能擴充。