之前我們已經講過,訂閱走 Paddle,手續費是 5% 加一筆固定額,模型費用使用者自己的 key。這一篇把那幾句換成數字:每個月固定支出多少、一筆訂閱實收多少、要幾個付費使用者才不虧。算出來之後,打平線比我原本想的低:訂閱裡沒有模型費,多一個付費使用者幾乎不增加我這邊的帳單。
之前我們已經講過為什麼訂閱不含模型費。放到成本帳上,效果是:多一個付費使用者,我這邊多出來的主要是他佔的那點資料庫空間。沒有模型費、沒有隨用量成長的帳單。包含 AI 用量的產品裡,重度使用者會把利潤吃光;這邊他就只是一份訂閱費。使用者要自己去申請一把 key,那是一道真實的門檻,會流失一部分人。我拿可預測的成本換這道門檻。
有一個例外:試用期裡,每個帳號前十次 agent 工作可以由平台代跑。
export const TRIAL_FREE_RUNS = Number(process.env.TRIAL_FREE_RUNS ?? 50);
/* The cheapest model that can hold a tool loop is not the cheapest useful one: flash-lite gets through the motions
but the pages it compiles are not worth the trial. Roughly 8x the token price, which the capacity page accounts for. */
const platformModel = () => process.env.PLATFORM_TRIAL_MODEL?.trim() || 'google/gemini-3.8-flash';
程式預設寫 50,線上用環境變數改成 10。試用是註冊起十四天的 Pro,期間 agent 工作不限次數,但其中只有前十次可以不填 key。那十次走平台在 OpenRouter 預付的額度,不是使用者自己的 key。儲值的位置在 OpenRouter 的 credits。
那個模型原本挑的是最便宜的 flash-lite,後來換掉了,理由就寫在上面那段註解裡:它跑得完流程,但編出來的頁面不值得拿來當試用。便宜的模型不會自己開概念頁,而概念頁正是這個產品跟一般摘要工具的差別。換過去之後,token 單價大約八倍。
實際量到的一次代跑大約 US$0.01 到 0.02。十次用滿,一個新註冊的人最多花掉兩毛美元。這筆跟註冊人數成正比,跟付費人數無關,算獲客、不算營運。十次是這樣定的:一次不夠感受複利,十次夠把幾份來源丟進來看概念頁長出來。再多就是在替不會付費的人付錢。
剩下的全是固定月費,不隨使用者成長:
| 項目 | 方案 | 月費 |
|---|---|---|
| 應用程式、Postgres、備份 cron | Railway Hobby | US$5,含額度;超出另計 |
| 網域 wikibrain.app | Cloudflare Registrar | US$14.20/年,約 US$1.18 |
| DNS、CDN、信箱轉址 | Cloudflare 免費方案 | US$0 |
| 寄信 | Resend 免費方案 | US$0 |
| 外部監控 | UptimeRobot 免費方案 | US$0 |
| Google 登入、GitHub Actions | 免費方案 | US$0 |
| 合計 | 約 US$6.18(Railway 不超出含額度時) |
Paddle 從每筆抽 5% 加 US$0.50,不是月費。OpenRouter 的預付額度算在試用獲客,也不進這張表。Claude Code 是開發工具,不算產品固定成本。備份排程掛在 Railway 同一個 Hobby 帳單裡,沒有另開一筆物件儲存月費。
這張表也做進了營運面板,每一項標上方案、月費與續約日。之前我們已經講過,續約日在十四天內會變成 /healthz 的一項 degraded,免得忘記的時候被自動續約一個已經不需要的方案。
export const PRO_MONTH_CENTS = 600, PRO_YEAR_CENTS = 6000;
Pro 方案每月 $6、每年 $60,年繳等於兩個月免費。
程式裡還有一個早鳥折扣:33.34% off、限前一百位,也就是每月 $4。但它預設是關的,要設 PADDLE_EARLYBIRD=1 才會生效,關掉的時候還會順手把已經建好的折扣封存。
export const EARLYBIRD_PERCENT = 33.34, EARLYBIRD_LIMIT = 100;
const enabled = process.env.PADDLE_EARLYBIRD === '1';
關掉的理由寫在那段註解裡:一個「還剩幾個名額」的計數器,等於公開你有幾個付費使用者。產品剛上線的時候,那個數字對你不利。功能先做好放著,等有本錢再打開。
手續費從約 3% 變成 5% 加一筆固定額。固定額對小額訂閱特別傷:$6 的訂閱,固定額佔的比例遠大於 $60 的年繳。所以:
月繳實收 = $6 × 0.95 − $0.50 = $5.20
年繳實收 = $60 × 0.95 − $0.50 = $56.50(平均每月 $4.71)
年繳的手續費占比低很多(約 5.8%,月繳約 13%),而且一次進帳,不只是現金流比較順。這是我後來把年繳放在定價頁預設選項的理由。
打平人數 = (固定成本 + 新註冊人數 × $0.20)÷ 每人實收
固定成本約 US$6.18,月繳實收 US$5.20,試用代跑即使用滿也只有兩毛。不計新註冊,打平要 兩個 月繳使用者;年繳攤成每月是 US$4.71,也是一到兩個。一個年繳訂閱一次進帳 US$56.50,單筆就蓋得住好幾個月的固定成本。一個月新增五十個註冊、其中兩個付費,試用最多再加十美元,兩份月繳訂閱還蓋得住。
成長本身仍有成本:換過更貴的模型之後,十次乘上去會再跳一次,這條線還是得盯著。數字比我原本預期的低,是因為不包模型費之後,固定成本就真的是固定的。
打平之後的下一個問題是能撐多少人。營運面板有一個試算,輸入免費、試用、付費各多少人,算出「還能收多少」與「最先撞到哪個上限」。
四個候選:
export const limitsFor = (plan: 'free' | 'pro'): PlanLimits => plan === 'pro'
? { notes: num('PRO_NOTES_LIMIT', 10_000), bytes: num('PRO_STORAGE_BYTES', 1024 ** 3), tokens: null, retentionDays: num('PRO_RETENTION_DAYS', 90) }
: { notes: num('FREE_NOTES_LIMIT', 200), bytes: num('FREE_STORAGE_BYTES', 20 * 1024 ** 2), tokens: num('FREE_TOKENS_LIMIT', 1), retentionDays: num('FREE_RETENTION_DAYS', 7) };
| 上限 | 目前的設定 |
|---|---|
| 資料庫儲存 | 免費 20 MB、Pro 1 GB |
| 筆記數 | 免費 200 頁、Pro 10,000 頁 |
| 無頭瀏覽器的並行 | 全機同時三頁 |
| 搜尋的全表掃描 | 之前我們已經量過,五千頁是換索引的門檻 |
最先撞到的是無頭瀏覽器:
const MAX_CONCURRENT = Math.max(1, Number(process.env.HEADLESS_CONCURRENCY ?? 3));
之前我們已經講過,它佔記憶體、一次只跑幾頁,而且是整個系統唯一一個「一個人可以影響到所有人」的資源。儲存反而很便宜,一座知識庫幾百頁的 Markdown 加起來還不到幾 MB。
前面說邊際成本幾乎歸零,指的是每個使用者的帳單。每一台機器能服務的人數還是有上限:多到某個程度還是得加機器,只是那時候加的是一整階,帳單不會隨人數線性長上去。知道哪一個上限最近,加的時候才不會花錢加錯東西。
免費方案:200 頁、20 MB、七天快照保留、每月二十次 agent 工作。這幾個數字回答的是「一個不付錢的人最多能讓我花多少」。之前我們已經講過,超過上限之後是唯讀:讀得到、刪得掉、匯出得了,不是把人鎖在資料外面。
唯讀的使用者還是佔著儲存。把人鎖在自己的資料外面會換來客訴跟壞名聲,那比幾 MB 貴得多。
這一篇在算抽完 Paddle 手續費之後,幾個付費使用者才蓋得住每月的固定成本。固定支出約 US$6.18,月繳實收 US$5.20,不計新註冊要 兩個 月繳使用者;試用代跑跟註冊人數走,算獲客、不算營運。訂閱不含模型費,所以打平幾乎只跟這張固定成本表有關。