PostHog warehouse, Nov 2026

Why PostHog left DuckDB, and why MotherDuck would not have saved it

A summary of PostHog's posts, plus answers to two questions the posts skip: why not DuckDB on DuckDB, and why not MotherDuck.

Short version

The problem was that DuckDB runs on one machine. Hosting it somewhere else does not change that. PostHog hit three walls: single-node sizing, a DuckLake catalog that did not scale, and the Postgres protocol layer. MotherDuck takes over running the servers, but it fixes none of the three.

Timeline

  1. Before 2026
    ClickHouse

    A shared, multi-tenant ClickHouse cluster. Modelling queries run for hours or days and break when nodes restart. No cost-based optimizer. Lake format support was slow to mature.

  2. Jun 29, 2026
    DuckDB + DuckLake

    One DuckDB instance per customer, DuckLake as the catalog with data in S3, and Duckgres, a Postgres wire protocol server, so dbt, BI tools and psql work.

  3. Nov 2, 2026
    Trino + HogLake

    Their own flavour of Trino and a new open table format, HogLake. Tested at PostHog's petabyte scale first, then design partners.

The three walls they hit

Single node

DuckDB sizing

  • The worker size has to be picked before the query arrives.
  • Queries were heavier than expected, so they needed huge instances.
  • Spilling to added disks would make queries too slow and expensive.
  • Slow S3 reads until async fetching landed recently.
  • No way to spread one database across machines.
Catalog

DuckLake at 2 PB

  • About 1 trillion rows and 15.3 million snapshots.
  • A one-table write took 3+ minutes. Each commit re-read stats for the whole catalog.
  • Over 99% of stats rows were for deleted tables. Cleaning gave 30 to 50 times faster writes, then they grew back.
  • Must stay compatible with the official schema, so deep tuning was blocked.
  • Many connections to shared Postgres. They ended up carrying a fork.
Protocol

Speaking Postgres

  • Long-lived connections are harder to scale than HTTP.
  • Little load-balancing tooling for pgwire. HTTP headers route better in Kubernetes.
  • Every client expects its own niche Postgres behaviour.
  • Coverage "never got good enough".

Why not DuckDB on DuckDB?

Not in the posts

Postgres had two separate jobs here, and neither was the query engine:

So a DuckDB engine on a DuckDB file makes the main problem worse: the engine on one machine was the weak point, not the storage.

Why not MotherDuck?

Not in the posts
MotherDuck takes over running the servers. It does not fix single-node sizing, the catalog, or the Postgres protocol.

The new tech, from their GitHub

Open source

The blog post gives no detail, but both pieces are public repos with real docs.

What HogLake changes vs DuckLake

Why not just Iceberg?

The README says it plainly: "Iceberg buys ubiquity: every engine already reads it and there is no service to operate." HogLake trades that for metadata in indexed SQL instead of many object-store round trips, plus one place that owns commit, compaction and expiry. An Iceberg REST facade is designed, so other engines can read it later.

Status

The benchmark numbers in the README (flat commit latency, about 380 commits/s) come from a laptop, so they show the shape, not production capacity.

Sources