Skip to content

Postgres CDC to Snowflake Final State Guide

June 2026

Postgres to Snowflake works when logical replication ordering and Snowflake MERGE rules agree on exactly which row version should win.

Short Answer

Postgres CDC to Snowflake works by reading inserts, updates, and deletes from PostgreSQL WAL logical replication and applying them with Snowflake MERGE DML. PostgreSQL provides committed LSN ordering and full row after images for updates. Snowflake provides _skippr_order_token VARCHAR columns, automatic tombstone tables, and MERGE logic that only updates a row when the incoming token is greater than the stored one.

For example, if public.customers id 212 changes city from "Austin" to "Denver", PostgreSQL emits the update through pgoutput and Skippr stores the committed LSN for restart safety. Snowflake MERGE updates id 212 only if that new token is newer than the current token in the table. If the row is deleted later, the tombstone ensures an older replayed insert cannot recreate it.

Why Teams Struggle with This

This integration only works cleanly when both the source replication setup and the destination merge rules are explicit. PostgreSQL needs wal_level = logical and a stable replication slot, while Snowflake final-state correctness depends on MERGE plus token comparison instead of simple batch arrival order.

  • PostgreSQL CDC requires logical replication through pgoutput.
  • Updates arrive as full row after images, which is what lets Snowflake replace the entire current row safely.
  • The replication slot is reused across restarts, so PostgreSQL keeps WAL only until Skippr confirms it.
  • Deletes rely on tombstones so newer deletes continue to beat older replayed inserts.

How Skippr Handles It

Skippr gives the integration one consistent contract. It stores the committed LSN after each committed batch, resumes the source stream from that point, and applies the ordered mutations to Snowflake with MERGE plus automatic order-token and tombstone management. The same ordering signal governs both restart safety and row reconciliation.

That matters when a specific Snowflake row is questioned. You can explain whether the latest WAL mutation was newer, whether Snowflake rejected an older replay, and whether a tombstone already recorded a delete for that key.

  • PostgreSQL logical replication with durable committed-LSN resumes.
  • Snowflake MERGE with _skippr_order_token guards on updates.
  • Automatic tombstone tables for delete protection.
  • A direct final-state path from WAL changes into Snowflake rows.

What the First Useful Version Looks Like

Use this integration when Snowflake is the warehouse consumers trust and PostgreSQL is the system generating the row changes.

The design stays clean when every team member can answer one question: which committed PostgreSQL mutation should Snowflake show as the current row right now?