Skip to content

This is the multi-page printable view of this section. .

Return to the regular view of this page.

Release Notes

Release notes and feature highlights for pg_mooncake, duckdb_mooncake, and moonlink.

1 - pg_mooncake 0.3.0: First PGSTY Release with DuckDB 2.0, pgrx 0.19.3, and PostgreSQL 14–18 Support

pg_mooncake 0.3.0 (together with duckdb_mooncake v0.0.2 and moonlink v0.0.1) is the first release maintained by PGSTY, delivering DuckDB 2.0 / pg_duckdb 1.2.0 compatibility, pgrx 0.19.3 across PostgreSQL 14–18, LSN-consistent columnstore snapshots, and a full RustSec dependency security audit.

pg_mooncake 0.3.0 — released alongside duckdb_mooncake v0.0.2 and moonlink v0.0.1 — is the first release of the Mooncake real-time analytics suite maintained by PGSTY:

Binary RPM and DEB packages for PostgreSQL 14, 15, 16, 17, and 18 across RHEL / Rocky / AlmaLinux 8, 9, 10 and Debian 12/13, Ubuntu 22.04/24.04 (x86_64 and aarch64) are available through the PGEXT repository and Pigsty.


Highlights of pg_mooncake 0.3.0

1. Upgraded to pgrx 0.19.3 & PostgreSQL 14–18

pg_mooncake has been migrated to pgrx = 0.19.3 (cargo-pgrx 0.19.3), bringing first-class support for PostgreSQL 18 alongside PostgreSQL 14, 15, 16, and 17:

  • Updated extension metadata in pg_mooncake.control (default_version = '0.3.0') and added the upgrade script sql/pg_mooncake--0.2.0--0.3.0.sql.
  • Replaced legacy C string literals with Rust native CStr (c"...") across GUC definitions (mooncake.timeline_id, mooncake.enable_local_bucket, mooncake.default_bucket, mooncake.enable_memory_metadata).

2. DuckDB 2.0.0 & pg_duckdb 1.2.0 Adaptation

pg_mooncake 0.3.0 embeds pg_duckdb v1.2.0 and duckdb_mooncake v0.0.2, built against DuckDB v2.0.0 (d54cbbe3df17e8e5ce68312f483b4155836112aa):

  • Ported duckdb_mooncake to the DuckDB 2.0 TableCatalogEntry, StorageExtensionInfo, and TableFilterSet iterator APIs.
  • Fixed column-index remapping for IS NULL and IS NOT NULL filter pushdown in MooncakeScanFunction, preventing segmentation faults when multi-column filters are pushed down to Moonlink Parquet scans.
  • Added a runtime pg_duckdb version check during worker initialization that enforces pg_duckdb = 1.2.0 (accepting 1.2.0 or 1.2.0-* pre-release suffixes and failing fast with a clear diagnostic message on mismatched versions such as 1.1.3 or 1.3.0).

3. LSN-Consistent Snapshot Reads (pg_current_wal_flush_lsn)

Previously, duckdb_mooncake constructed Moonlink table scan descriptors with lsn = 0, returning immediately without waiting for recently committed PostgreSQL transactions to be ingested by the background logical replication worker.

In v0.3.0, pg_mooncake exports mooncake_get_postgres_lsn() (calling pg_current_wal_flush_lsn() when in a normal backend session and 0 during recovery), and duckdb_mooncake resolves that symbol via dlsym(RTLD_DEFAULT, "mooncake_get_postgres_lsn"). Every analytical query against a columnstore table now waits until Moonlink has caught up to the PostgreSQL WAL flush LSN before scanning.

4. Partitioned Table Hierarchy Support (REPLICA IDENTITY FULL)

When calling mooncake.create_table(dst, src) on a partitioned PostgreSQL table, pg_mooncake 0.3.0 now walks the inheritance tree (find_all_inheritors) and sets REPLICA IDENTITY FULL on both the parent table and every leaf partition before adding the root table to the logical replication publication.

5. Explicit 0A000 Error for Deprecated mooncake.load_files

The legacy v0.1 helper mooncake.load_files(dst TEXT, files TEXT[]) now raises ERRCODE_FEATURE_NOT_SUPPORTED (0A000) with a clear migration message instead of silently panicking (todo!()).

6. Cargo Dependency Security Audit (RustSec)

All three Cargo workspaces (pg_mooncake, moonlink, duckdb_mooncake/moonlink_ffi) underwent a comprehensive security remediation against the RustSec Advisory Database (2026-11-05):

  • pg_mooncake/Cargo.lock: reduced vulnerabilities from 33 to 6 (-82%) and eliminated all unsoundness warnings (1 -> 0).
  • moonlink/Cargo.lock: reduced vulnerabilities from 46 to 15 (-67%) and eliminated all unsoundness warnings (1 -> 0).
  • duckdb_mooncake/moonlink_ffi/Cargo.lock: 0 vulnerabilities, 0 unsound, 0 warnings.
  • Upgraded tonic 0.14.5, prost 0.14.3, bincode 2.1.0, opentelemetry 0.31.0, wasmtime 43.0.1, rustls 0.23.37, aws-lc-rs 1.16.3, bytes 1.11.1, tar 0.4.45, and lz4_flex 0.11.6. See the SBOM & Security Audit page for full details.

Validation Summary

pg_mooncake 0.3.0 was validated end-to-end on both Ubuntu 24.04.5 LTS ARM64 (PostgreSQL 18.6) and Rocky Linux 10.2 ARM64 (PostgreSQL 17.11):

  • 58/58 Moonlink table_handler unit tests passed.
  • 3/3 pg_Regression SQL suites (small, partition, unsupported) passed (0 failures).
  • Runtime version check verified: rejected pg_duckdb 1.1.3 and 1.3.0, accepted 1.2.0.
  • 11/11 real-time replication, UPDATE/DELETE, partition, Iceberg metadata, and crash-restart persistence checkpoints passed.

2 - pg_mooncake v0.2: what we're cooking

The release where out-of-the-box analytics becomes reality: logical replication into columnstore tables, rowstore write buffering, and Apache Iceberg.

With v0.1, we proved that Postgres can deliver great analytics performance. Our approach combined two key pieces—DuckDB vectorized engine and a columnstore table—making pg_mooncake the only extension in Postgres that integrates both.

The results speak for themselves: pg_mooncake ranks in ClickBench’s top 10, and we built the fastest Parquet-based engine along the way.

Now, with v0.2, we’re tackling the next big challenge; we call it out-of-the-box analytics.

First, why in-Postgres analytics?

Applications often have their first analytics needs far before they have their first data warehouse or analytics system.

We’ve seen this story over and over again. The typical path involves delaying the roadmap, setting up data replication into a separate system, hiring engineers to maintain the pipeline—all while stitching Postgres data with analytics data at the application level.

pg_mooncake eliminates this complexity. With columnstore tables, developers get a native Postgres experience for both transactional and analytical workloads. No separate systems, no complex pipelines—just Postgres.

In v0.2, we are focused on making columnstore tables easier to get started for more workloads. In this blog, we cover the areas under active development:

1. Full Postgres Table Access Method (TAM) for Columnstore Tables (#80)

In v0.1, all columnstore queries ran through DuckDB. This delivered performance, but meant missing Postgres features like data-modifying CTEs (e.g., deleting rows, returning results, and inserting them into another table) and triggers.

In v0.2, we explore exposing columnstore tables through a Postgres table access method and logical replication architecture, allowing DuckDB to serve as the fast execution engine while preserving full Postgres table compatibility.

2. Logical Replication into columnstore tables (#90)

Users often adopt pg_mooncake after encountering slow queries on their existing Postgres tables. With logical replication, we make it even easier to accelerate analytics without changing application write patterns—simply replicate data from heap tables into columnstore tables via mooncake.create_table.

This significantly enhances pg_mooncake’s deployability, no matter where your Postgres is hosted. You can run pg_mooncake alongside your existing Postgres deployments and seamlessly replicate data from heap tables into columnstore tables.

3. Small Inserts with an In-Memory / Rowstore Buffer (#89)

Logical replication introduces a challenge: how do we handle frequent small inserts without generating a new Parquet file and metadata log for every transaction?

In v0.2 (powered by Moonlink), small inserts go into an Arrow write buffer, while background flushes write compacted Parquet files. When querying a columnstore table, duckdb_mooncake scans both the buffered data and Parquet files. Once the buffer exceeds a threshold, it flushes to Parquet. This approach decouples Parquet writes from OLTP transactions, significantly reducing write amplification.

This is a major unlock, making columnstore tables viable for high-concurrency OLTP mirroring without requiring batched inserts—especially for logging, HTAP, and time-series workloads.

So, where does that put us?

pg_mooncake is the easiest way to get fast analytics inside Postgres. With v0.2 (and PGSTY’s v0.3.0 release), key use cases improve even further:

  1. User-facing analytics with Postgres – Full ORM support, joins with regular Postgres tables, and only 1 system to manage.
  2. Logs, chat history, time series – Optimized for high-rate ingest with the benefits of Parquet compression and low storage costs.
  3. Complete Data Lake out of the box – Postgres + pg_mooncake writing data transactionally to Apache Iceberg, combined with the fastest Parquet-based execution with file skipping and segment elimination.

3 - The easiest way to Analytics in Postgres: pg_mooncake v0.1

pg_mooncake comes out of beta, bringing native columnstore tables and DuckDB vectorized execution to Postgres.

We announced pg_mooncake to the world on Day 60.

Today, Day 131, pg_mooncake comes out of beta.

pg_mooncake wins on ease and performance. So, we doubled down for v0.1. That’s it.

The Easiest Way to Fast Analytics in Postgres

With a native columnstore table in Postgres, pg_mooncake brings familiar table semantics to the way you run analytics. Columnstore tables support transactional operations like INSERT, SELECT, UPDATE, DELETE, and COPY, alongside joins with regular Postgres heap tables.

In v0.1, we’ve made it even easier to load data into columnstore tables:

  1. From Parquet, CSV, and JSON files:
SELECT * FROM mooncake.read_parquet('<file_path>');
  1. From Hugging Face datasets:
COPY reddit_comments FROM 'hf://datasets/fddemarco/pushshift-reddit-comments/data/RC_2012-01.parquet';
  1. From existing Iceberg and Delta Lake tables:
SELECT * FROM mooncake.iceberg_scan('s3://bucket/table');

Better performance for time-series workloads

pg_mooncake is the only Postgres extension that adds columnar storage and vectorized execution.

In v0.1, we added file statistics and skipping. Customers run time-series and analytics workloads without traditional sharding.

Our ClickBench results land next week. (Hint: top 10 🙂). Perhaps Postgres is indeed a Great Real-Time Analytics Database.

Looking Ahead to v0.2

We will double down on two areas: DevEx and time-series workloads. Planned improvements include:

  1. Enhanced support for small writes, updates, and deletes
  2. Syncing rowstore tables to columnstore tables
  3. Indexes (secondary indexes and sort keys)
  4. Time-series functions

To our community, thank you

It takes a village. Thank you to our community, customers, contributors, and Postgres partners like Neon and Supabase. Your support has been invaluable.

Our favorite metric is the number of contributors to pg_mooncake growing.

The momentum behind pg_mooncake is clear. Analytics in Postgres is indeed a reality 🥮