DuckLake in Production: The Honeymoon Phase Is Officially Over

DuckLake in Production: The Honeymoon Phase Is Officially Over

PostHog just moved its warehouse off DuckDB and DuckLake after five months. Here’s what that means for the rest of us running DuckLake in production.

Five months. That’s how long it took PostHog to go from “we rebuilt our entire warehouse on DuckDB” to “we’re rebuilding it again, this time without DuckDB.” The postmortem dropped this week, and the data engineering community collectively winced.

Here’s the uncomfortable truth: the DuckLake stack that looked so elegant on a laptop turns out to have some sharp edges when you point real production traffic at it. The question isn’t whether DuckDB is brilliant, it is. The question is whether the DuckDB + DuckLake combo was ever actually built for the workloads we’re shoving at it.

The DuckLake Promise vs. The PostHog Reality

The pitch for DuckLake was seductive: a lakehouse format from the same creators as DuckDB, designed for simplicity and near-universal compatibility. Ditch the warehouse, keep the SQL, store everything as Parquet. What’s not to love?

PostHog loved it enough to dogfood it hard. They put all of PostHog into a DuckLake as their first customer. That meant roughly 2 PB of data, about 1 trillion rows, and 15.3 million snapshots. This wasn’t a cautious pilot, it was a full commitment.

DuckDB and DuckLake logo with a production-ready checkmark, illustrating the blog post about moving off DuckDB
DuckDB and DuckLake: brilliant on a laptop, challenging in production.

And it broke.

Not in the fun “we found a bug and patched it” way. It broke in the “this architectural decision is fundamentally wrong for our scale” way.

The Catalog Tax Nobody Talks About

Here’s the detail that should make you nervous if you’re running DuckLake: a single-table write could take more than three minutes because every commit re-read the statistics for the entire catalog.

Think about that. You’re not writing to a massive distributed system. You’re writing to a catalog that’s supposed to be lightweight and portable. And yet, as your lake grows, every commit becomes a full-catalog scan.

But wait, it gets worse. Over 99% of the catalog’s statistics rows belonged to tables that no longer existed. When they cleaned those up, writes got 30 to 50 times faster. And then the orphaned rows grew right back.

This is the operational tax that nobody mentions in the lakehouse keynote. And it’s not unique to DuckLake, Iceberg has its own version of this tax, but DuckLake’s commitment to portability made it worse.

The Compatibility Cage

DuckLake’s catalog schema has to stay portable across many SQL databases. That’s a feature for adoption, but it’s a straightjacket for optimization. PostHog’s team found themselves wanting to tune indexes and tweak the schema, only to hit a wall: staying 100% compatible with the “official” DuckLake schema meant fewer optimization options.

They ended up carrying patches in a fork.

Let me repeat that: they had to fork DuckLake to make it work at their scale. And forking an open-source project means you lose the main benefit of using it, the community. You’re now maintaining your own private version of a format that’s supposed to be standardized.

Single-Node Brilliance, Cloud-Sized Problems

DuckDB is genuinely one of the best things to happen to data engineering. It’s probably the best single-node tool for analyzing heaps of data, and that node can be your laptop. It’s robust, reliable, and almost always finishes your query, spilling to disk when memory runs out.

But those same features that make it great locally turn into headaches in the cloud:

  • Instance sizing becomes a guessing game. You can’t predict CPU and memory needs for a specific query, which means you either over-provision (expensive) or under-provision (slow).
  • No async fetching from S3. DuckDB only recently added this. For a warehouse product fetching lots of data from object storage, this was a major bottleneck.
  • Scaling out requires huge instances. You can’t just add a node, you have to size the worker before the query arrives.

For a tool that prides itself on not making you think about infrastructure, this is a significant gap.

The Postgres Wire Protocol Trap

Here’s a lesson that extends far beyond DuckDB: offering direct Postgres connections over port 5432 sounds like a great idea until you have to scale it.

PostHog’s team spent a huge amount of time handling the long tail of Postgres client compatibility. Each client expects its own niche behavior, and customers kept asking them to fix their specific library. Missing reconnects, managing TTLs and idle connections at scale, long-running connection costs, it all adds up.

Compare that to HTTP, where you have mature load-balancing tooling (AWS ALB vs NLB is like comparing a sports car to a tractor), flexible routing in Kubernetes, and a standardized protocol that clients mostly agree on.

The lesson: wire protocol compatibility is a product feature, not a technical checkbox. And it’s a feature that’s genuinely hard to get right.

So, Is DuckLake Production-Ready?

Let’s be precise about what PostHog’s experience does and doesn’t tell us.

It doesn’t tell us DuckLake is useless. For smaller datasets, gigabytes to low terabytes, DuckDB and DuckLake might be the perfect stack. There are real production deployments out there, like the ones mentioned in the r/dataengineering discussion, folks running Sling, DuckLake, dbt, and Dagster in a deliberately minimalist stack. The “SQL-native, keep it simple” philosophy has real appeal for teams that don’t want to run a distributed warehouse.

But it does tell us something important: DuckLake was built for compatibility, not scale. The design choices that make it portable across databases are the same design choices that make it hard to optimize for a specific engine. And when you’re at the point where tables have more than 15 million snapshots, “compatibility” stops being a feature.

The pattern here is familiar. DuckDB became popular because it’s brilliant at a specific thing: analyzing data on a single machine. DuckLake extends that philosophy to lakehouse storage. But the lakehouse problem, multi-tenant, distributed, always-on, is fundamentally different from the embedded analytics problem. The tools that win at one don’t automatically win at the other.

What Comes Next?

PostHog is rebuilding on Trino with their own open table format called HogLake. They’ve also published a fascinating ducklake-defect-ledger documenting what they found. It’s a brutally honest look at what happens when a tool designed for one workload gets stretched to another.

Meanwhile, AWS’s acquisition of DuckLabs raises real questions about where DuckDB and DuckLake go next. Does DuckDB 2.0’s server mode change the calculus? Does the DuckLake SDK’s decoupling from DuckDB make the format more flexible?

These are genuinely interesting developments. But the core tension remains: DuckLake chose compatibility and simplicity over scale and optimization. That’s a legitimate choice, but it’s also a ceiling.

For most teams, the takeaway isn’t “don’t use DuckDB.” It’s:

  • Match the tool to the workload. DuckDB is incredible for analytics on a single machine. It is not a distributed warehouse, and DuckLake’s catalog design doesn’t change that.
  • Watch your catalog growth. If you’re storing statistics for tables that no longer exist, you’re paying a tax you shouldn’t be paying.
  • Be careful with protocol promises. “Works with any Postgres client” is a much harder promise than it sounds.

PostHog’s decision to move off DuckDB after five months says less about DuckDB and more about the gap between “works great on my laptop” and “works great as a managed multi-tenant service.” That gap is where production-ready dies.

The data stack is evolving quickly, and the lines between transactional databases and lakehouses are blurring. But one thing hasn’t changed: production readiness requires more than a brilliant demo. It requires understanding your failure modes at scale and having a plan for them. DuckLake’s failure modes are now public knowledge, which is honestly a gift to everyone evaluating it.

Whether the DuckLake community can address those failure modes, or whether HogLake and other forks will supersede it, is the question that will define the next year of lakehouse architecture.

Share:

Related Articles