指南 / 2026-09-24
SaaS 部署选 Cloudflare Workers + D1 还是 Vercel + Postgres?ShipKit 为什么选 Cloudflare
同样一个 SaaS,跑在 Workers、D1、R2 上和跑在 Vercel 加托管 Postgres 上,1 千和 1 万用户时每月各花多少钱,附计算过程。Cloudflare 给了你什么、拿走了什么,什么时候该选另一边。

大多数 SaaS 启动模板默认用 Vercel 加托管 Postgres。ShipKit 选的是 Cloudflare:应用跑在 Workers 上,数据库用 D1,文件放 R2。这个决定决定了模板里其他所有东西,包括框架。这篇讲清楚我们的考虑:钱、开发体验,以及 Cloudflare 确实更差的那些地方。
下文所有价格都来自各家官方定价页,核对日期是 2026 年 9 月 24 日。价格会变,做决定前请再查一遍。
账单
两个粗略的场景。假设:每个请求约 10 毫秒 CPU,一个以读为主的普通应用,10% 的请求是下载文件。
| 每月约 1,000 用户 | 每月约 10,000 用户 | |
|---|---|---|
| 请求数 | 30 万 | 500 万 |
| 数据库 | 1 GB | 5 GB |
| 文件 | 5 GB | 50 GB |
| Cloudflare(Workers 付费版 + D1 + R2) | 约 $5 | 约 $6–7 |
| Vercel Pro + Neon + Vercel Blob | 约 $33–40 | 约 $60–80 |
这些数字是怎么来的:
- Cloudflare 的 $5 是 Workers 付费版的最低消费,对这个规模的产品来说几乎全包了:每月含 1000 万次请求和 3000 万 CPU 毫秒;付费版的 D1 含 250 亿行读取、5000 万行写入和 5 GB 存储;R2 免费提供 10 GB 存储,下载流量永远不收费。到 1 万用户时,唯一多出来的只是几美分的 CPU 时间,以及超出 R2 免费 10 GB 的那部分存储费。
- Vercel Pro 每个能部署的成员 $20/月,含 $20 的用量额度,两个场景的用量都在额度之内。但到了 500 万次请求,就超过了 Pro 包含的 100 万次 CDN 请求,下一档要再加 $20。
- Neon 是最大的变量。 存储很便宜,计算按实际运行的小时收费:流量稳定的应用会让它一直醒着,在这两个场景里大约是每月 $13–40,取决于计算规格。Supabase Pro($25/月,含 8 GB 数据库和 100 GB 文件存储)也是合理的替代,还能顺便替掉 Blob。
还没开始收钱的阶段,差距更大。Workers 的免费版(每天 10 万次请求)能以 $0 跑一个还没上线的产品;而按 Vercel 自己的合理使用规则,Hobby 版只能用于非商业用途,收款就算商业用途。一个收费的 SaaS,从第一笔订单起就得用 Pro。
这些数字都不算大。如果 Vercel 真的让一个创始人效率更高,他不该为了每月省 50 美元去换平台。但差距不是零,而且会叠加:在 Cloudflare 上,每个预览项目、副业项目和演示站都共用同一个 $5。
除了价格,你还得到什么
绑定,而不是凭证。 在 Worker 里,D1 和 R2 是绑定:由运行时直接交给你代码的对象。没有会泄露的连接字符串,不用调连接池大小,没有要轮换的 S3 密钥,流量高峰时也不会出现"连接数过多"的错误。ShipKit 只在一个文件里读取所有绑定,代码库的其他地方都不知道数据库是怎么连上的。
本地和线上是同一个运行时。 ShipKit 的开发服务器把服务端代码跑在 workerd 里,也就是 Workers 背后的开源运行时,本地的 D1 和 R2 也通过同样的绑定访问。"我电脑上能跑"在这里是有意义的。
文件下载不收流量费。 R2 不收下载费。对于要提供用户上传文件、头像或生成文件的产品,在其他平台上最容易让人吓一跳的往往就是这一项。
其他东西都在同一个账号里。 定时任务是 wrangler.jsonc 里的一行;限流是一个绑定(ShipKit 在公开接口上用了它);DNS、TLS 和 CDN 随域名一起就有了。一个控制台,一张账单。
默认全球部署。 Worker 在离每个访客最近的地方运行,你不用给应用选区域。
你要付出的代价
这些代价是真实的,每一条都花过我们的时间。
- D1 是 SQLite。 快、便宜,但没有交互式事务:
db.transaction()会直接报错,官方文档给出的多条写入原子化方式是batch()。ShipKit 就是按这个写的:扣余额用一条带条件的语句,几条写入必须一起成功时用 batch。详见《D1 没有交互式事务,怎么安全地扣余额》。 - 容量上限。 付费版的单个 D1 数据库最大 10 GB。对大多数 SaaS 绰绰有余,对少数产品就是一道硬天花板。
- 没有 Postgres 生态。 没有扩展(pgvector、PostGIS、Postgres 式的全文搜索),没有行级安全,SQL 能力也弱一些。如果你的产品需要其中任何一项,D1 就是错误的数据库。
workerd不是 Node。 开启nodejs_compat后大部分包能用,但不是全部;运行时eval被禁止,一些 MDX 和模板引擎的做法因此用不了。ShipKit 已经绕开了我们碰到的那些。- 单个请求有 CPU 限制。 长时间运行的任务,比如视频处理或大批量导出,需要换一种设计(队列,或者交给别的服务)。
- 平台绑定。 绑定是 Cloudflare 独有的概念,以后要换平台,就得替换数据库层、文件存储、定时任务和限流。那是几天的工作量,不是一个下午的事。
什么时候该选 Vercel 和 Postgres
- 你的产品需要 Postgres 的能力:扩展、大量关联查询和报表、行级安全,或者数据库会超过 10 GB。
- 你需要长时间运行的服务端任务,而且没法拆成短任务。
- 你的团队已经在 Vercel 上,而且用得很顺手。每月几十美元能买到很多熟悉感。
- 你想在生产环境用 Next.js 加 React Server Components,这个组合在 Vercel 上状态最好。
如果你属于这些情况,一开始就选一个基于 Postgres 的模板,别跟 SQLite 较劲。我们的 TanStack Start 模板对比里列了好几个。
为什么 ShipKit 只支持 Cloudflare
我们考虑过两边都支持。但 Drizzle 的 schema 是按数据库写的,两边都支持就意味着两套 schema、两套迁移历史、每个功能的测试都要两份。以后每加一个功能都要做两遍,让模板保持可靠的那些检查也会跟着翻倍。我们宁愿把一个平台做好。
所以 ShipKit 是给想要 Cloudflare 这些好处的人准备的:一个在有真实流量之前每月只花 $5 左右的 SaaS,没有连接字符串,也没有流量账单。登录、支付、后台管理和国际化都已经在上面跑起来了。看看包含什么,或者先打开在线演示,它就跑在同一套技术栈上。


