為什麼選 Cloudflare Workers 不選 AWS Lambda:給獨立開發者的決策框架

在 ClinCalc / ExClinCalc / Kaizei 我都選了 Cloudflare Workers。本文說明這個選擇的具體理由、踩到的限制、以及什麼情況下我會反過來選 Lambda。

#cloudflare-workers#aws-lambda#edge-computing#infrastructure#architecture

TL;DR

我所有上線的專案(兩個醫療系統 + 一個個人理財桌面應用的後端)都選 Cloudflare Workers,不選 AWS Lambda。主要理由是冷啟動 / 成本 / 整合,但這個選擇有具體限制 ── 不是所有場景都適合。本文是我自己的決策框架,給類似背景的獨立開發者參考。


兩個平台的本質差異

兩者都被叫做「serverless」,但底層架構差很多:

AWS Lambda
  └─ 容器化 Node.js / Python / Java...
      └─ 在 region(如 us-east-1)啟動實例
          └─ 經 API Gateway / ALB 對外

          冷啟動:50ms ~ 數秒(依語言 + 大小)

Cloudflare Workers
  └─ V8 Isolate(不是容器)
      └─ 跑在全球 300+ 邊緣節點
          └─ 直接對外

          冷啟動:< 5ms(一致)

核心差異:Lambda 是「region-scoped 容器」,Workers 是「global edge V8 isolate」。


我選 Workers 的具體理由

1. 冷啟動

醫療資訊系統與桌面應用的 API call 都是低頻 / 突發型。冷啟動每次都要付。

實測:

平台冷啟動Warm 後延遲
Lambda(Node.js, 256MB)200–600ms30–80ms
Lambda(Java)1000–3000ms50–100ms
Cloudflare Workers< 5ms(一致)< 30ms

對「使用者點按鈕等回應」這種互動,Worker 的延遲一致性比 Lambda 的偶發冷啟動好

2. 成本(免費 tier)

我的三個專案目前的真實月成本:$0。能做到是因為:

Cloudflare Workers
  └─ 100,000 req/day(免費)
      └─ 我三個專案總請求量 < 5,000/day → 永遠不爆

AWS Lambda
  └─ 1M req/month + 400,000 GB-seconds(免費)
      └─ 加 API Gateway / CloudWatch / S3 / DynamoDB 各自有獨立帳單
          → 容易破掉

Lambda 本身免費 tier 大方,但真實要跑一個 web app 還要 API Gateway + DynamoDB + S3 + CloudWatch,每個都有獨立帳單,常常實際 $5–20 / 月起跳。

3. 整合

Cloudflare 自己有完整生態:KV(key-value)、D1(SQLite)、R2(S3 相容物件儲存)、Pages、Durable Objects。Worker 可以直接用,不需要組接

ExClinCalc 的請求路徑:
  使用者 → CF Pages (frontend) → CF Worker (API) → CF KV (rate limit) → Supabase (DB)
  全部一個帳號內、一個 dashboard 看完

對單人開發者,減少 vendor 數 = 減少維護成本


Workers 的真實限制

公平來說 ── Workers 不是萬靈丹。我踩到的限制:

限制 1:CPU 時間

免費 tier:每個請求 10ms CPU 上限
付費 tier (paid Workers):30s CPU 上限

「CPU 時間」不是「總時間」── 是 V8 實際運算的時間(不含等網路 IO)。多數 API call 沒事,但重度運算(PDF 生成、影像處理、大量加密)會撞牆

我的對策:把重度運算丟到使用者裝置 / 其他 service。例如 Kaizei 的 PBKDF2 跑在桌面端、Worker 只做認證。

限制 2:不能直接連 PostgreSQL

PostgreSQL 是 TCP 協定,但 Workers 早期不支援原生 TCP socket(現在透過 Hyperdrive 或 PG-bouncer 可以,但配置麻煩)。

我的對策:透過 Supabase 的 PostgREST HTTP API。這是設計取捨:HTTP layer 多一道,但 Workers 不用搞 connection pool。

限制 3:Runtime 限制

V8 isolate 不是完整 Node.js runtime。許多 npm 套件在 Workers 跑不起來:

  • 用了 fs / child_process 的套件不行
  • 大型套件(Puppeteer、Sharp)不行
  • 需要原生編譯(如 bcrypt)的不行 → 改用 Web Crypto API

我的對策:選 Workers 友善套件、必要時用 Web Crypto / Streams API 自己實作。

限制 4:Debug 比 Lambda 難

Lambda 有 CloudWatch logs + X-Ray。Workers 有 wrangler tail + Workers Logs,但功能比 CloudWatch 簡單

我的對策:local dev 用 wrangler dev 完整模擬、production debug 用 logpush 推到外部 log service。


什麼情況我會反過來選 Lambda?

不是「Workers 永遠贏」── 有幾個情境我會選 Lambda:

情境為什麼選 Lambda
需要跑 Python / Java / Go 等非 JS 語言Workers 只支援 V8 / WASM
需要重度運算(PDF / 影像 / ML inference)Lambda CPU 時間放寬到 15 分鐘
需要直接整合 AWS 服務(Step Functions、SQS 等)Workers 對接 AWS 要額外 SDK
法規要求資料留 specific regionLambda 可指定 region;Workers 邊緣全球
已在 AWS 生態(VPC、RDS、IAM)不該為了 Workers 重做 IAM

對「一個獨立開發者做 web app」── Workers 多半贏。對「企業級多服務整合」── Lambda 多半贏。


一個常被忽略的點:Workers 的 stateless 比 Lambda 更乾淨

Lambda 容器在熱啟動時「可能」復用記憶體狀態(global 變數可能殘留)。這在實務上常造成神奇 bug:「為什麼有時候會帶到上一個 user 的資料?」

Workers 的 V8 isolate 每個請求都是新 context,沒有跨請求狀態殘留風險。對醫療系統這種「資料隔離至上」的場景,這個特性減少一大類 bug


給類似背景的人

如果你是獨立開發者 / 學生 / 小團隊在做 web app,我會給以下建議:

Pick Workers if…

  • 你的 stack 是 TypeScript / JS
  • 主要做 web API + frontend,沒有重度運算
  • 想要全球低延遲
  • 想要免費 tier 走得遠
  • 不想管 region 設定 / VPC

Pick Lambda if…

  • 你的 team 已經在 AWS 生態
  • 需要非 JS 語言
  • 需要 long-running compute(> 30s)
  • 要對接 AWS specific services

兩個都不對 if…

  • 你的負載是穩定 + 高頻 → 直接租 VM 或 Container 更便宜
  • 你需要 stateful 連線(WebSocket 持久連線)→ Workers Durable Objects 或自己架

開放問題:邊緣運算在醫療場域的取捨

「Workers 全球邊緣節點」對民眾端 ClinCalc 是純加分(全球低延遲)。但對醫療場域有疑慮

  • 法規可能要求醫療資料留境內 → Workers 邊緣全球節點可能違規
  • 醫師要的不是低延遲 50ms,是 audit 一致性 / 災備
  • 免費 tier 限流如果突發爆量會 throttle,醫療系統 SLA 要求高

這個議題沒有簡單答案。我目前的折衷是:把資料層留在 region-locked 的 Supabase,Workers 只做計算 / 路由 / API gateway。資料留境內、計算邊緣化。

但這仍是憑直覺、缺量化評估。是我希望進研究所深入的方向之一。


延伸閱讀