Skip to content

Cloudflare Hyperdrive 怎麼用:讓 Workers 接上既有 Postgres / MySQL

2026年8月30日 1 分鐘
TL;DR Hyperdrive 解的是 Workers 連到既有 Postgres / MySQL 的延遲與連線池問題。它用 edge connection setup、靠近資料庫的 connection pool、read query cache,讓單區資料庫比較適合被全球 Workers 存取。
目錄
  1. Hyperdrive 的位置
  2. 它怎麼讓單區資料庫變快
  3. 建立 Hyperdrive configuration
  4. Workers 裡怎麼用
  5. Query caching:好用,但要知道哪裡不能用
  6. Connection pooling 的幾個坑
  7. Observability:看 cache status 和 pool 壓力
  8. Limits 和 pricing
  9. 什麼時候不該用 Hyperdrive
  10. production 前的檢查清單
  11. 參考資料

🌏 English version

把 API 搬到 Cloudflare Workers 後,資料庫通常是第一個卡住的地方。你可能已經有一顆 PostgresMySQL 跑在 AWS、GCP、Azure、Neon、Supabase、PlanetScale、RDS、Aurora。應用程式可以跑在全球邊緣,資料庫卻仍在某個 region。

Cloudflare Hyperdrive 解的是這個縫隙:Workers 這種 serverless runtime 從世界各地連到既有資料庫時,連線建立太慢、連線數太多、熱門 read query 重複打回 origin。它不要求你把資料搬到 D1,也不要求你改掉 ORM。它提供一個 Workers binding,讓你用原本的 driver 連到 Hyperdrive,再由 Hyperdrive 管 connection pool 和可快取的 read query。

這篇放在 Cloudflare Edge Platform 的 D1、Durable Objects、Queues、Workflows 後面,因為它處理的是很常見的遷移題:「我不想重寫資料層,但想把 app runtime 搬到 Cloudflare。」

Hyperdrive 的位置

Hyperdrive 最適合接在「Workers app」和「既有關聯式資料庫」中間。

Browser / API client
        |
        v
Cloudflare Worker
        |
        v
Hyperdrive binding
        |
        +--> connection setup near Worker
        +--> connection pool near database
        +--> optional read query cache
        |
        v
Existing Postgres / MySQL

官方文件把 Hyperdrive 描述成讓既有區域資料庫「像全球分散式資料庫一樣被存取」。這句要小心讀。資料仍然在原本的資料庫;transaction、schema、write path、backup、replication、migration 都還是你的資料庫負責。Hyperdrive 幫你處理的是 Workers 連過去的網路與連線層。

它和其他 Cloudflare data services 的分工可以這樣看:

需求服務
新專案需要 SQLite 關聯式資料庫D1
既有 Postgres / MySQL 要給 Workers 存取Hyperdrive
每個 entity 需要強一致狀態、鎖、WebSocketDurable Objects
慢工作或批次處理Queues
多步驟長流程Workflows

如果你還沒選資料庫,而且資料模型適合 SQLite,D1 比較簡單。如果資料已經在 Postgres/MySQL,或團隊已經有 Prisma、Drizzle、Kysely、node-postgres 這套工具,Hyperdrive 通常是遷移成本比較低的入口。

它怎麼讓單區資料庫變快

Workers 是分散在全球的 runtime。傳統資料庫通常在單一 region,而且連線建立很貴。Cloudflare 的 getting started 文件把這個成本拆得很直:真的送出 SQL 之前,TCP、TLS、資料庫 authentication 可能已經消耗多個 round trips。

Hyperdrive 用三件事處理這個問題:

  • Edge connection setup:Worker 先和附近的 Hyperdrive 建立連線,少掉從使用者所在地一路連到資料庫 region 的握手成本。
  • Connection pooling:Hyperdrive 在靠近 origin database 的區域維持連線池,盡量重用既有 database connections。
  • Query caching:對可快取的 read-only query,Hyperdrive 可以直接回 cached response,減少 origin database load。

這代表兩個設計結論。

第一,如果 request 只打一個 query,Worker 靠近使用者通常仍然合理;Hyperdrive 已經處理連線建立和 pool。第二,如果一個 request 會連續打多個 uncached query,Cloudflare 文件建議考慮 Placement,把 Worker 放近資料庫 region,避免每個 SQL round trip 都跨半個地球。

{
  "placement": {
    "region": "aws:us-east-1"
  }
}

這不是每個 Worker 都要設定。它適合資料庫互動密集、而且 query 無法靠 cache 吃掉的 request path。

建立 Hyperdrive configuration

Hyperdrive 目前支援 Postgres、MySQL,以及相容協定的資料庫。官方支援表列出 PostgreSQL 9.0 到 17.x、MySQL 5.7 到 8.x,也列出 Aurora、Neon、Supabase、Timescale、Materialize、CockroachDB、PlanetScale、MariaDB 等相容服務。SQL Server 和 MongoDB 目前不支援。

建立時給它資料庫 connection string:

npx wrangler hyperdrive create app-prod-db \
  --connection-string="postgres://user:password@database.example.com:5432/app"

或 MySQL:

npx wrangler hyperdrive create app-prod-db \
  --connection-string="mysql://user:password@database.example.com:3306/app"

成功後 wrangler 會回傳 Hyperdrive config id,放進 wrangler.jsonc

{
  "compatibility_date": "2026-08-30",
  "hyperdrive": [
    {
      "binding": "HYPERDRIVE",
      "id": "<your-hyperdrive-id>"
    }
  ]
}

如果你的 Worker compatibility date 在 2026-08-04 以前,資料庫 driver 需要 nodejs_compat flag;2026-08-04 以後的 Workers/Pages 專案,Cloudflare 文件寫明 Node.js compatibility v1/v2 預設啟用,不需要再用這些 flags 打開。舊專案可以保留既有設定,不必為了更新日期硬刪。

本機開發可以加 localConnectionString

{
  "hyperdrive": [
    {
      "binding": "HYPERDRIVE",
      "id": "<your-hyperdrive-id>",
      "localConnectionString": "postgres://local:local@127.0.0.1:5432/app"
    }
  ]
}

正式 connection string 不該進 repo。用 wrangler 建 config 時把 secret 交給 Cloudflare,Worker 裡只拿 binding。

Workers 裡怎麼用

Postgres 範例用 pg 很直覺:

import { Client } from "pg";

export default {
  async fetch(request, env): Promise<Response> {
    const client = new Client({
      connectionString: env.HYPERDRIVE.connectionString,
    });

    try {
      await client.connect();
      const result = await client.query(
        "SELECT id, title FROM posts WHERE published = $1 ORDER BY created_at DESC LIMIT 20",
        [true],
      );

      return Response.json({ posts: result.rows });
    } finally {
      await client.end();
    }
  },
} satisfies ExportedHandler<{ HYPERDRIVE: Hyperdrive }>;

看起來像每個 request 都 new client,這在一般 Node server 會讓人緊張。但 Hyperdrive 文件特別說,可以每次建立 client,因為底層 database connection pool 由 Hyperdrive 維持。

MySQL 則可以用 mysql2/promise,並把 Hyperdrive binding 拆成 host/user/password/database/port:

import { createConnection } from "mysql2/promise";

export default {
  async fetch(request, env): Promise<Response> {
    const connection = await createConnection({
      host: env.HYPERDRIVE.host,
      user: env.HYPERDRIVE.user,
      password: env.HYPERDRIVE.password,
      database: env.HYPERDRIVE.database,
      port: env.HYPERDRIVE.port,
      disableEval: true,
    });

    try {
      const [rows] = await connection.query(
        "SELECT id, title FROM posts WHERE published = ? ORDER BY created_at DESC LIMIT 20",
        [true],
      );
      return Response.json({ posts: rows });
    } finally {
      await connection.end();
    }
  },
} satisfies ExportedHandler<{ HYPERDRIVE: Hyperdrive }>;

disableEval: true 是 Workers runtime 的現實限制:mysql2 不能用 eval-based parser。

Query caching:好用,但要知道哪裡不能用

Hyperdrive 預設開啟 query caching。預設 max_age 是 60 秒,stale_while_revalidate 是 15 秒,max_age 最高可以設到 1 小時。

它會解析 database protocol,判斷 query 是 mutating 還是 non-mutating。SELECT 這類 read-only query 有機會被 cache;INSERTUPDATEDELETECREATE 不會。Postgres 的 NOW()CURRENT_TIMESTAMPRANDOM()LASTVAL() 這類 stable/volatile function 也不會被 cache。文件建議把這種時間值移到應用程式,當參數傳進 SQL。

-- 比較容易 cache:時間由 app 算好後當參數傳入
SELECT * FROM events WHERE created_at > $1 ORDER BY created_at DESC LIMIT 50;

最大警告是 read-after-write。Hyperdrive 不會在你的 app 寫入資料庫時自動清掉相關 read cache。也就是說,剛寫完一筆資料,下一個一模一樣的 SELECT 仍可能在 max_age 內拿到舊結果。

我的預設切法是兩組 Hyperdrive configuration:

npx wrangler hyperdrive create app-prod-cached \
  --connection-string="<DATABASE_CONNECTION_STRING>"

npx wrangler hyperdrive create app-prod-fresh \
  --connection-string="<DATABASE_CONNECTION_STRING>" \
  --caching-disabled

Wrangler 綁兩個 binding:

{
  "hyperdrive": [
    {
      "binding": "DB_CACHED",
      "id": "<cached-config-id>"
    },
    {
      "binding": "DB_FRESH",
      "id": "<cache-disabled-config-id>"
    }
  ]
}

用法很簡單:

  • 公開內容、商品目錄、排行榜、dashboard summary:走 DB_CACHED
  • auth、session、permission、billing、admin settings、寫入後立刻讀:走 DB_FRESH

這樣比全域關掉 cache 更務實。你仍然保留熱門 read 的加速,也不會把一致性需求藏在某個 SQL comment 或 application convention 裡。

Connection pooling 的幾個坑

Hyperdrive 的 pool 是 transaction mode。query 或 transaction 結束後,connection 會回到 pool,並做 reset。這帶來幾個實務影響:

  • 不要假設 connection-level SET 會留到下一個 query。
  • 如果每個 query 都需要特定 session setting,就每次 query/transaction 明確設定。
  • 不要為了保留 SET 狀態,把一堆操作包成長 transaction;長 transaction 會卡住 pool,降低 Hyperdrive scaling。
  • 如果有多個 Hyperdrive config 指向同一個資料庫,要把總 connection 數一起算。

官方 limits 頁目前列出的每個 configuration origin database connections 約是 Free 20、Paid 100,最小連線數是 5。這些是靠近 origin database 的連線,不是 Workers client concurrency;Hyperdrive 不限制 Workers 到 Hyperdrive 的 concurrent client connections。

你最該監控的是 pool 有沒有卡住。常見錯誤包含:

  • Failed to acquire a connection from the pool.
  • Server connection attempt failed: connection_refused

前者通常代表 connection 被長 query 或長 transaction 卡太久;後者常見於 firewall、ACL、資料庫 provider connection limit。

Observability:看 cache status 和 pool 壓力

Hyperdrive 提供 dashboard metrics,也能透過 GraphQL Analytics API 查。官方文件列出兩組 dataset:

  • hyperdriveQueriesAdaptiveGroups
  • hyperdrivePoolSizesAdaptiveGroups

我會先看這幾個指標:

  • query volume
  • query latency
  • connection latency
  • cache status:hitmissuncacheablevolatiletransactionparseerror
  • avg/max open connections
  • waiting clients

volatile 特別有用,代表 query 裡有 Postgres stable/volatile function,例如 NOW()RANDOM(),導致 cache 不生效。waitingClients 上升則代表 pool 壓力變大,該查長 query、transaction、connection count,或確認 database provider 的連線上限。

Limits 和 pricing

截至 2026-08-30 查到的官方文件:

  • Hyperdrive 可用於 Workers Free 和 Paid plans。
  • Free plan 每天 100,000 database queries;Paid plan database queries unlimited。
  • database query 指任何經 Hyperdrive 發出的 statement,包含 SELECTINSERTUPDATEDELETECREATEALTERDROP
  • Free 最多 10 個 configured databases;Paid 最多 25 個。
  • initial connection timeout 15 秒,idle connection timeout 10 分鐘。
  • query statement duration 上限 60 秒。
  • cached query response size 上限 50 MB;超過仍會回給 Worker,但不會 cache。
  • connection pooling 和 query caching 在 Workers Paid plan 內含,不另外收費。
  • Hyperdrive 不收 data transfer / egress。

這些數字容易變,正式發布前要再重查 pricing 和 limits。文章裡真正穩定的判斷是:Hyperdrive 的成本與限制主要看經過它的 database statements、configuration 數、origin connection pool、query duration,而不是傳統 app server 那種機器規格。

什麼時候不該用 Hyperdrive

幾個情境我不會先選 Hyperdrive:

  • 新專案資料量小、schema 單純,直接用 D1 比較省。
  • request 需要大量長 transaction 或 connection-level session state。
  • 資料庫完全在 private network,且你還沒設 Workers VPC 或對外連線方案。
  • 主要瓶頸是 SQL 本身太慢,缺 index、缺查詢優化;Hyperdrive 只能減少連線與網路成本,不能修壞掉的 query plan。
  • 你需要多區寫入、一致性 replication、資料庫 HA;那些仍然是 database layer 的事。

比較好的使用場景:

  • 既有 SaaS 後端想把 API edge 化,但資料庫短期不能搬。
  • Postgres/MySQL 已經是團隊標準,ORM 和 migration pipeline 都成熟。
  • 大量全球 read traffic 打到同一個資料庫。
  • 熱門 read 可以接受 15 到 60 秒等級的短暫 stale。
  • Workers 需要接 Neon、Supabase、Aurora、PlanetScale 這類既有資料庫。

production 前的檢查清單

上線前我會逐項確認:

  • database hostname 是 public DNS;若是 private network,先設 Workers VPC。
  • TLS 設定正確;Hyperdrive 不支援 insecure plaintext database connection。
  • database user 權限剛好足夠,不用 root/admin。
  • compatibility date 與 Node.js compatibility 符合 driver 需求。
  • Postgres driver 版本符合官方最低版本;MySQL driver 設好 disableEval
  • public read 和 fresh read 分成不同 Hyperdrive binding。
  • auth、permission、billing、read-after-write 不走 cached binding。
  • long transaction 有 timeout 和監控。
  • GraphQL / dashboard metrics 會看 cache status、query latency、pool size、waiting clients。
  • database provider firewall / ACL 允許 Hyperdrive 連線。

Hyperdrive 的價值不在於取代資料庫,而是在你不想重寫資料層時,讓 Workers 比較自然地接上現有 Postgres/MySQL。對 Edge Platform 來說,它是一個遷移橋:先把 runtime 搬近使用者,再逐步決定哪些資料該留在原本資料庫,哪些該搬到 D1、R2、KV 或 Durable Objects。

參考資料