DuckLake is the built-in data lakehouse that backs every Panels project. It stores data as Parquet files, uses DuckDB for query execution, and provides versioning, schema evolution, and a queryable catalog out of the box.
TODO: This page needs full content.

How DuckLake works

When you materialize a node’s output, Panels writes the results as Parquet files managed by DuckLake. Subsequent queries against that node read directly from Parquet — fast columnar scans without hitting the original source.

Versioning

DuckLake tracks snapshots of every table. You can query historical versions and compare data across runs.

Schema evolution

When a node’s output schema changes (new columns, type changes), DuckLake handles the migration automatically.

Open formats

All data is stored as standard Parquet files. You can export data at any time — no vendor lock-in.

PIVOT aggregate aliases

Panels supports DuckDB PIVOT queries, including generated columns and multiple aggregates. Add explicit aliases when a multi-aggregate PIVOT uses expressions such as count(*), casts, unary operators, or functions with multiple arguments.
Panels does not reproduce every DuckDB rule for automatically naming columns from complex aggregate expressions. Without explicit aliases, Panels rejects these queries during SQL reference validation and asks you to add aggregate aliases. This fail-closed behavior prevents a generated output from being mistaken for a physical column.
For example, write:
The aliases produce predictable names such as 2024_row_count and 2024_total_population. Basic aggregate forms such as sum(population) and avg(population) can continue to use DuckDB’s default generated names.