發表文章

為什麼我們將後端從 Vercel 遷移到 Cloudflare Workers

前言

最近我們完成了一次重要的基礎架構遷移——將 API 服務從 Vercel 移至 Cloudflare Workers。這個決策背後有兩個核心原因:雙重 Cold Start 問題讓回應速度慢到無法接受,加上 Vercel 的 Wall Time 計費方式在資料庫等待期間仍然持續收費,讓成本悄悄膨脹。

在 Serverless 的世界裡,這兩個問題往往被低估。即便程式碼已優化至極致,API 回應依然頻繁出現顯著的「長尾延遲」——P99 的劇烈波動不只是技術數字,它直接影響用戶留存與體驗。

問題一:致命的「雙重冷啟動」

什麼是 Cold Start?

Cold Start(冷啟動)是指服務在閒置一段時間後,收到新請求時需要重新初始化執行環境所花費的時間。對使用者來說,這段等待就是莫名其妙的「卡頓」。

我們遇到的情況

我們的技術棧中有兩個環節各自都有 Cold Start 問題:

1. Vercel Serverless Function 的 Cold Start

Vercel 的傳統 Serverless Functions 本質上構建在容器化架構(主要基於 AWS Lambda)之上。當請求觸發冷啟動時,系統必須經歷「容器準備 → Node.js 運行時加載 → 程式碼初始化」的完整過程。這種 Cold Boot of the Runtime 是性能的首要殺手,冷啟動時間約在 200ms ~ 1500ms 之間浮動。

雖然 Vercel 近年推出了 Fluid Compute 技術,透過位元組碼快取與預測性實例升溫將冷啟動延遲降低約 80%,但對於流量不穩定的服務,Cold Start 幾乎無法完全避免。

2. TiDB Serverless 的 Cold Start

我們的資料庫選用了 TiDB Serverless(分散式 NewSQL 資料庫),它同樣採用 Serverless 架構——在閒置時會自動暫停以節省成本,被喚醒時需要額外的 1000ms ~ 3000ms 來重新建立連線池(Connection Pool)與運算節點暖機。

雙重疊加的災難

使用者發出請求
      ↓
Vercel Cold Start(+200ms ~ 1.5 秒)
      ↓
TiDB Cold Start(+1~3 秒,等待連線池建立與節點就緒)
      ↓
實際執行查詢(+數百毫秒)
      ↓
回應使用者(總計:3~6 秒以上)

當兩個 Cold Start 同時發生,使用者等待超過 5 秒才得到回應,體驗極差,甚至觸發前端的 timeout 錯誤。冷啟動不僅是技術指標的延遲,P99 延遲的劇烈波動會直接損害用戶留存率。

問題二:Vercel 的計費黑洞——Wall Time vs CPU Time

這是很多人忽略的坑。

Vercel Functions 的計費單位是 GB-seconds,計算的是函式從開始執行到回傳回應的完整掛鐘時間(Wall Time),而不是實際消耗 CPU 的時間(CPU Time)。

這代表什麼?

函式開始執行
      ↓ ← 計費開始(包含以下所有等待)
等待 TiDB 冷啟動(1~3 秒,CPU 完全閒置)
      ↓
等待資料庫查詢回應(數百毫秒,CPU 完全閒置)
      ↓
回傳回應 ← 計費結束

CPU 什麼事都沒做,帳單照跑。 當 TiDB 需要 2 秒冷啟動時,Vercel 就向你收了 2 秒的運算費用,哪怕你的程式碼在那 2 秒內完全沒有執行任何邏輯。

對於像我們這樣資料庫 Cold Start 頻繁的服務,這個計費模式直接把成本放大了好幾倍。

為什麼選擇 Cloudflare Workers?

1. V8 Isolates:架構上的降維打擊

Cloudflare Workers 採用了與傳統容器截然不同的技術路徑:V8 Isolates

不同於需要引導整個作業系統的容器,Cloudflare Workers 運行在 V8 引擎的隔離空間中。這些 Isolates 共享同一個運作進程,但擁有完全隔離的記憶體空間。因為省去了加載作業系統與容器鏡像的步驟,其啟動速度通常低於 10ms

平台 平均冷啟動 最大冷啟動 架構類型
Cloudflare Workers < 10ms 50ms V8 Isolates
Vercel Edge Runtime < 20ms 100ms V8-based
Vercel Functions (Regional) 200ms 1500ms Container-based

V8 Isolate 的三大優勢:

  • 極速啟動:消除傳統 Node.js 運行時加載的開銷
  • Stateless 設計:強制執行無狀態設計,天然適合高併發 API 場景
  • 高安全性:利用瀏覽器級別的沙箱機制確保程式碼安全

2. 全球邊緣網路:讓 API 離用戶更近

Cloudflare 在全球擁有超過 300 個節點,讓 95% 的全球人口在 50ms 內即可觸達其網路。請求不需要跳轉到特定的雲端區域中心,而是直接在離用戶最近的邊緣節點執行邏輯。

從業界延遲數據來看,Cloudflare Workers 在所有邊緣運算平台中表現最為突出:

平台 全球平均延遲 P90 延遲 P99 延遲
Cloudflare Workers 25ms 40ms 75ms
Vercel Edge Runtime 35ms 55ms 90ms
Netlify Edge Functions 45ms 70ms 110ms
Vercel Functions 70ms 120ms 250ms
Netlify Functions 85ms 140ms 280ms

值得注意的是,即使是 Vercel 的 Edge Runtime(同樣是邊緣架構),延遲也比 Cloudflare Workers 高出約 40%。而傳統 Serverless Functions 的 P99 更高達 250ms,尾端延遲極不穩定——這對 API 密集型應用是相當嚴重的問題。

3. 計費只算 CPU Time,I/O 等待不收費

Cloudflare Workers 只對實際的 CPU 執行時間計費,等待 I/O(資料庫查詢、外部 API 呼叫)的時間完全不計入帳單。

計費項目 Cloudflare Workers (Paid) Vercel (Pro)
起步價格 $5 / 月 $20 / 月
包含請求數 1,000 萬次 1,000 萬次 (Edge)
額外請求費 $0.30 / 百萬次 $2 / 百萬次
流量費用 $0(無出站流量費) 超過 1TB 需按量計費
計費方式 CPU Time only Wall Time (GB-seconds)

對我們來說,TiDB 冷啟動的那 1~3 秒,在 Cloudflare 上完全不收費。這一項差異,讓整體運算成本顯著下降。

4. 更可預測的效能曲線

V8 Isolate 的輕量特性讓 Workers 的執行效能更穩定。從數據可以看到,Cloudflare Workers 的 P99(75ms)與平均延遲(25ms)差距僅 3 倍,而 Vercel Functions 的 P99(250ms)與平均(70ms)差距超過 3.5 倍。效能的可預測性,對維運穩定性至關重要。

遷移後的實際效果

遷移完成後,我們觀察到以下改善:

  • 首次請求回應時間(Cold Start 情境):從平均 4~6 秒 降至 1~3 秒(僅剩 TiDB 的 Cold Start)
  • 一般請求回應時間(暖機後):從 200~400ms 降至 50~150ms
  • Timeout 錯誤率:幾乎降為零
  • 運算成本:因不再對 I/O 等待時間計費,費用顯著下降

遷移的挑戰與注意事項

遷移並非毫無代價,以下是我們遇到的實際挑戰:

  • 執行環境限制:Cloudflare Workers 不支援完整的 Node.js API,部分套件需要替換或調整。
  • 記憶體上限:單個 Worker 的記憶體限制為 128MB,需要注意資源使用。
  • 本機開發體驗:需要使用 Wrangler CLI,與 Vercel 的 vercel dev 有所不同,需要一段時間適應。
  • 不適合所有場景:若你高度依賴 Next.js 的 ISR(增量靜態生成)或 Server Actions,Vercel 仍有不可取代的優勢。

架構師的建議:混合策略

完全搬離 Vercel 並非唯一選項。我們最推薦的實戰路徑是混合架構(Hybrid Approach)

前端交給 Vercel,邊緣 API 邏輯交給 Cloudflare。

利用 Vercel 託管 Next.js 前端以享受最佳的開發體驗與 ISR 性能;同時將 API Gateway、速率限制(Rate Limiting)與對延遲敏感的服務部署在 Cloudflare Workers。這種架構能同時發揮 Vercel 的 DX 優勢與 Cloudflare 的網路底層優勢。

什麼時候該堅守 Vercel?

  • 極度依賴 Next.js 特定功能(ISR、Server Actions)
  • 需要多語言運行環境(Node.js、Python、Go)
  • 追求 Git 集成與自動化預覽環境的極速開發流程

什麼時候該遷移至 Cloudflare?

  • 後端有 Cold Start 的資料庫(如 TiDB Serverless、PlanetScale 等)
  • 需要全球化低延遲 API,P99 穩定性要求高
  • 流量大且預算有限,需要最大化成本效益

結語

這次遷移讓我們學到兩件事:

第一,在 Serverless 架構中,每一層的 Cold Start 都會疊加。當資料庫本身就有 Cold Start 問題時,選擇啟動成本極低的運算平台是第一優先。

第二,Wall Time 計費在 I/O 密集的場景下是個隱形成本炸彈。當函式大部分時間都在等資料庫,而平台卻把等待時間全部計入帳單,成本會遠超預期。

Cloudflare Workers 同時解決了這兩個問題:V8 Isolate 消除了運算層的 Cold Start,CPU Time 計費讓 I/O 等待不再燒錢。2026 年的邊緣運算版圖已經清晰——技術選型應回歸數據本質:你的架構是在為用戶節省時間,還是在消耗他們的耐心?

如果你也在使用 TiDB Serverless 或其他有 Cold Start 的資料庫,這個組合值得認真評估。

張貼留言