月成本 $0 部署完整 CDSS:Cloudflare + Supabase 免費 tier 實戰

兩套上線中的醫療資訊系統 + 一個個人理財桌面後端,月成本 $0。本文是我實際走過的部署路徑、踩過的坑、以及這個方案能 / 不能 scale 到哪。

#deployment#cloudflare#supabase#free-tier#infrastructure#indie-dev

TL;DR

ClinCalc + ExClinCalc + Kaizei 三個系統的真實月成本:$0。靠的不是省錢魔法,是針對「免費 tier 邊界」設計架構。本文寫給類似背景的獨立開發者:怎麼做、能撐到哪、什麼情況下需要付費。


我目前的真實帳單

直接攤開來:

服務用途免費額度我的用量月費
Cloudflare Pages前端託管(3 個專案)無限頻寬、500 builds/月< 100 builds/月$0
Cloudflare WorkersAPI 後端(3 個 Worker)100K req/day< 5K req/day$0
Cloudflare KVrate limit / 簡單快取1GB 儲存、100K 讀/day微量$0
Cloudflare DNS4 個子網域不限4 個$0
Supabase 專案 #1ClinCalc DB + Auth500MB DB、1GB 儲存< 50MB$0
Supabase 專案 #2ExClinCalc DB + Auth同上< 30MB$0
Supabase 專案 #3Kaizei vault同上< 10MB$0
GitHub程式碼 + Actions公開 repo 免費、2000 min Actions< 200 min/月$0
Resend認證 email 寄送100 封/day< 30 封/day$0
Gemini APILLM 翻譯 / OCR(ClinCalc)限速但有月配額突發$0–3
合計$0–3

Gemini 是唯一不確定 ── 用量大時會收費,但 ClinCalc 流量低,目前都在免費配額內。


為什麼這個組合可行

關鍵不是「找最便宜的 vendor」,是選免費 tier 邊界跟我的負載特性匹配的服務

Cloudflare:邊緣免費 tier 對低頻負載友善

免費 tier:100,000 req/day(= ~ 1.16 req/s 平均)

對「個人開發、小規模上線」── 這個額度大到天荒地老。我三個 Worker 加起來目前 < 5,000 req/day,連 5% 都用不到。

關鍵特性:沒有冷啟動懲罰。Lambda 免費 tier 也大方但每次冷啟動付延遲,Workers 沒這問題。

Supabase:每專案 500MB 資料庫對醫療 / 個人應用夠用

免費 tier:500MB DB、1GB storage、50,000 monthly active users

醫療系統的單個診所資料量不大(病人清單 + 病歷 + 處方)。我 ExClinCalc 的測試 DB 有 50 個病人 + 數百筆 SOAP 病歷 + 處方 ── 用了不到 30MB。

關鍵限制:閒置 7 天會被 pause。需要 keepalive(下節說)。

GitHub:公開 repo + Actions 免費

公開 repo 無限 + 2000 分鐘 Actions/月。我的 deploy + keepalive 加起來大概 200 分鐘/月,遠在限額內。


踩到的坑(依嚴重度排)

坑 1:Supabase 免費 tier 7 天 pause

最大的雷。Supabase 為了控制免費 tier 成本,專案連續 7 天沒查詢就會被 pause。pause 後使用者首次造訪會延遲 2-3 秒喚醒。

對 ClinCalc / ExClinCalc 沒上線給真實使用者前 ── 我自己一個禮拜不開系統很正常。導致面試前打開系統,被 pause、demo 卡住。

對策:GitHub Actions 每天 02:00 UTC ping 一次 Supabase health endpoint:

# .github/workflows/keepalive.yml
name: Supabase Keepalive
on:
  schedule:
    - cron: '0 2 * * *'

jobs:
  ping:
    runs-on: ubuntu-latest
    steps:
      - name: Ping Supabase
        run: |
          curl -X GET "${{ secrets.SUPABASE_URL }}/rest/v1/" \
            -H "apikey: ${{ secrets.SUPABASE_ANON_KEY }}" \
            -H "Authorization: Bearer ${{ secrets.SUPABASE_ANON_KEY }}"

從此沒再被 pause。

坑 2:CF Workers 不能直接連 PostgreSQL

Workers V8 isolate 早期不支援原生 TCP socket。直接 pg.connect() 不行

對策:透過 Supabase 的 PostgREST HTTP API。多一層 HTTP 開銷,但 Workers 不用 manage TCP connection pool。Hyperdrive 現在能解但配置麻煩,對我規模不必要。

坑 3:Worker CPU 限制 10ms

免費 tier 每個請求 CPU 時間 10ms 上限。一般 API 沒事,但重度運算(PBKDF2 310,000 iterations、JSON.parse 大型 payload)會撞牆

對策

  • 重度加密放使用者裝置(Kaizei 的 PBKDF2 在桌面 Electron 端跑)
  • 大型 JSON 用 Streams API 邊讀邊處理
  • 必要時升級到 paid Workers(每月 $5,CPU 上限 30s)

坑 4:Cloudflare KV 寫入有 strong consistency 延遲

KV 的 write 是 eventually consistent ── 寫入後可能要 60 秒才在所有邊緣節點看到。

對我影響不大(rate limit 容忍延遲),但**「寫入後馬上要讀到」的場景不能用 KV**。要用 D1(SQL)或 Durable Objects。


部署流程(10 分鐘上線)

如果你也想複製這個方案,從零部署一個 Astro 網站到 Cloudflare Pages:

# 1. 開 repo + push 上 GitHub(公開 repo)
git init
git add .
git commit -m "initial commit"
gh repo create my-site --public --source=. --push

# 2. 上 Cloudflare Dashboard → Pages → Create Project
#    - Connect to Git → 選你的 repo
#    - Framework preset: 你用的 framework(Astro/Next/Vite)
#    - Build command: 自動填好
#    - Build output: dist 或 build
#    - Environment variables: 加你的 secrets

# 3. Save and Deploy → 5 分鐘後拿到 URL
#    - https://my-site-xxx.pages.dev

之後每次 git push 自動 deploy。


這個方案的天花板

「$0 / 月」不是無限可擴。明確說一下天花板:

天花板 1:流量

Cloudflare Workers 免費:100K req/day
→ ~ 3M req/month
→ 約撐到 ~ 100,000 月活躍使用者(看使用模式)

如果 ClinCalc 突然爆紅(新聞報導),可能需要升級到付費 Workers ($5/月,無限請求 + 30s CPU)。但這時候已經有「值得付費的問題」可以解了

天花板 2:資料量

Supabase 免費:500MB DB
→ 數十萬筆一般 row 數據
→ 約撐到中型診所(500 病人 + 多年病歷)

到極限要付 $25/月升 Supabase Pro(8GB DB + 無 pause)。

天花板 3:寫入併發

Supabase 免費 tier 連線數有限(PgBouncer 約 30 個 transaction pool)。如果 100 個使用者同時寫入 ── 排隊。

對單一診所沒問題,多診所同時上線可能有狀況。

天花板 4:客服 / SLA

免費 tier 沒有 SLA、沒有客服回應承諾。Supabase 真的掛掉 ── 等他們修。

對醫療正式上線是不能接受的。面試 / demo 階段可以,產品化要重新評估


什麼時候該升級

我的決策樹:

免費 tier 跑得順 → 繼續免費

某項服務開始抖(pause / 慢 / throttle)→ 看看是哪一項

只是 keepalive 沒做好 → 修 keepalive,繼續免費

真的負載上來 → 升級那一項,繼續其他免費
  
通常順序:Supabase Pro ($25) → Workers Paid ($5) → CF Pages Pro

不要從第一天就開全部付費。量化你的真實負載 → 找瓶頸 → 針對性升級


不適合這個方案的情況

公平講 ── 不是所有專案都該走「$0 / 月」路線:

  • 企業客戶要 SLA → 直接付費 / 自架
  • 資料量很大(GB 級)→ 免費 tier 不夠
  • 法規要求資料留特定 region → CF 全球邊緣可能不合
  • 需要 stateful 長連線(WebSocket 24/7)→ Workers 不適合
  • 需要 long-running compute → Lambda / VM 比較合

對「個人作品 / 學生 demo / 小規模初創前期」── 我這個方案非常合適。


一個觀察

走過這個方案兩年下來,最大的觀察是:

「免費 tier」不是單純省錢,是「強迫設計者問正確的問題」

我為了塞進 100K req/day 上限,學會了在 Worker 內做有效快取。 為了 500MB DB 上限,學會了 schema 設計時就思考 storage growth。 為了 10ms CPU 上限,學會了把重度運算丟到客戶端。

這些技能在我之後做更大規模專案時也用得到。免費 tier 不是退路、是訓練場。


延伸閱讀