产品分析公司 PostHog 最近干了一件不太像产品分析公司会干的事——他们把核心数据库从 ClickHouse 换成了 DuckDB,然后发现生态不够用,于是自己写了三个组件补上。
一个 PG 协议服务器、一个 DuckDB 扩展、再加一个新湖仓格式的深度集成。
PostHog 把整个架构叫「Tidy Trinity」:DuckDB 管计算,DuckLake 管存储,Duckgres 管连接。一个产品分析工具开始做数据库基建——这件事本身就值得拆开看。

架构图
● ● ●
为什么要离开 ClickHouse
PostHog 自己写过一篇文章讲 ClickHouse 和 DuckDB 的关系,用了个很妙的比喻:ClickHouse 是洋葱,DuckDB 是 spring onion。
什么意思?ClickHouse 大而全,功能丰富,但它是独立服务器进程——要部署、要管集群、要预留资源。DuckDB 是嵌入式库,进程内运行,零配置。
对 PostHog 来说,关键差异在于「单租户」。他们的新数据仓库产品是给每个客户一个独立的 DuckDB 实例,不是共享集群。这就天然避开了 ClickHouse 多租户的 noisy neighbor 问题。
而且 DuckDB 不持久化数据——它读的是对象存储里的 Parquet 文件,数据跟计算完全解耦。客户的数据存在自己的 S3 桶里,DuckDB 只是临时启动一个进程来查。
● ● ●
Duckgres:让 DuckDB 会说 PostgreSQL
这是整个架构里我最感兴趣的部分。
Duckgres 是 PostHog 用 Go 写的一个服务器,完整实现了 PostgreSQL Wire Protocol v3。纯 Go,两千多行代码。它的作用就一个——让你用任何 PG 客户端连 DuckDB。
psql、pgAdmin、lib/pq、psycopg2、dbt、Hex、Tableau——只要能连 PostgreSQL,就能连 Duckgres。
这招很聪明。PostHog 不需要自己写 SQL 编辑器,不需要自己写建模工具,甚至不需要自己写 BI——他们只需要让 DuckDB 跟 PG 协议兼容,剩下的交给 PG 生态。
Duckgres 干的活包括:
- PG 协议的简单查询和扩展查询(Prepared Statements、二进制格式、参数化查询)
- TLS 加密 + 明文密码鉴权
- 每个用户独立数据库文件(物理隔离)
- COPY 协议(批量导入导出)
- 启动时自动挂载 DuckLake 目录
- 限流和优雅关闭
启动方式极其简单:go build -o duckgres . && ./duckgres
,监听 5432 端口,完事。
● ● ●
DuckHog:用 Arrow 协议飞数据
如果 Duckgres 是对外的接口,那 DuckHog 就是 DuckDB 的原生扩展。
DuckHog 是 PostHog 写的一个 DuckDB Extension,让任何 DuckDB 实例都能直接连 PostHog 托管仓库。传输层用的是 Apache Arrow Flight SQL——列式传输,零序列化开销。
用法也很直接:
ATTACH 'hog://user:pass@warehouse.posthog.com' AS posthog; SELECT * FROM posthog.events WHERE timestamp > '2026-06-01';
ATTACH 之后,PostHog 仓库的表就跟本地表一样用,可以跟本地数据 JOIN。DuckHog 内部做了四件事:注册 hog:
协议、Arrow Flight SQL 客户端、虚拟目录映射、类型转换。
● ● ●
DuckLake:把元数据塞进 SQL 数据库
传统湖仓格式(Iceberg、Delta Lake)的元数据是用文件层级管理的——一堆 JSON、Avro 文件写来写去。DuckLake 的思路完全不同:元数据直接存在 SQL 数据库里,PostgreSQL、SQLite、DuckDB 都行。
这带来了几个好处:真正的 ACID 跨表事务、快照以行存储(可以百万级快照无性能退化)、小增量更新直接写进元数据表(不用写一堆小文件)。
PostHog 选择 DuckLake 而不是 Iceberg,赌的是深度集成带来的性能优势。DuckLake 是 DuckDB 创始团队做的,跟 DuckDB 的 ducklake
扩展是原生的。在单租户场景下,每个客户独立元数据用 PostgreSQL 托管,比 Iceberg 的 metastore + catalog 多层架构轻得多。
● ● ●
单租户隔离:不是逻辑隔离,是物理隔离
PostHog 的隔离方案是真·单租户,不是逻辑层面的:
- 每个客户独立 DuckDB 进程
- 独立对象存储路径
- Duckgres 按用户分配独立数据库文件
- 独立凭证
这意味着没有 noisy neighbor、没有共享集群的安全审计麻烦、弹性更高。代价是资源利用率比共享集群低,但这个坑 PostHog 通过完全托管填上了——用户不用管底层有多少个进程。
● ● ●
真实情况:还在 Beta,有自知之明
写到这儿必须说一句:截至 2026 年 6 月,PostHog 的 DuckDB 数据仓库还在 Beta 阶段,需要加入 waitlist。生产环境跑的还是 ClickHouse。
而且 PostHog 在产品页上标注了三处「还不适合」:
- 数据建模 → 推荐自带 dbt
- SQL 编辑器 → 推荐自带 Hex
- 商业智能 → 推荐自带 Hex
这说明他们很清楚自己现在的位置。数据仓库目前适合的是「产品团队做产品分析 + 偶尔 JOIN 一下 Stripe 数据」的场景。真要做严肃的数据工程,你得自己带工具。
另外有些结构性限制短期内解决不了:没有语义层、只有 36 个数据源(数据平台动辄 500+)、事件中心的数据模型对业务指标(收入、CAC、LTV)支持有限。
● ● ●
所以这说明了什么
Duckgres 的模式可以直接复用。Go 写 PG 协议 + 任意 DB 后端——不限于 DuckDB。把某个分析引擎包装成 PG 兼容的服务,整个 PG 生态的工具就能直接接进来。
单租户 DuckDB 有机会成为一个新品类。Snowflake 和 BigQuery 是共享基础设施 + 逻辑隔离,PostHog 选的是物理隔离 + 托管运维。对中小规模场景,这可能比租一个 Snowflake 实例更便宜也更简单。
DuckLake 的实验也值得盯着。如果它的生态能起来,在「单机 DuckDB + 对象存储」这个场景下,它比 Iceberg/Delta Lake 更合适。但前提是生态真的能起来——现在除了 DuckDB 本身,几乎没有其他引擎支持 DuckLake。
说到底,PostHog 在赌一件事:产品分析工具的下半场不是加更多功能,是变成数据平台。DuckDB 是引擎,Duckgres 是桥梁,DuckHog 是加速器,DuckLake 是地基。Beta 转 GA 之后的数据,会告诉我们这个局能不能成。




