/

Data Infrastructure

Postgres to Snowflake: The Complete Replication Guide

Intergalactic Data Labs

โ€”

โ€”

14 min read

Table of contents

Summarize

Updated October 19, 2026

To replicate Postgres to Snowflake, you read changes from the Postgres write-ahead log through logical replication, seed each table from one consistent snapshot, and MERGE those changes into typed Snowflake tables. Nine tools run this route today. Fivetran, Airbyte, Estuary, and Snowflake Openflow are the managed options, dlt and Debezium are the build-it-yourself options, and Filament by Galaxy is the one that checksums every batch on both sides of the write and runs as a single binary inside your own network.

Tool

Route maturity

CDC method

Integrity

Deploy

Pricing unit

Filament

Source beta, sink alpha

pgoutput

CRC32-C per batch, checkpoints

Binary, Go library, Helm

None

Fivetran

GA, Postgres 10 to 18

pgoutput or query-based

Vendor managed

SaaS

Monthly active rows

Airbyte

Certified source, direct-load destination

pgoutput or cursor

Typed final tables

Self-managed or Cloud

Credits on Cloud

Estuary Flow

Supported, Postgres 10 plus

pgoutput plus watermarks

Transactional apply

SaaS, private, BYOC

Per GB plus per connector

Openflow (Snowflake)

Snowflake native, Postgres 11 to 18

pgoutput, Snowpipe Streaming

Journal tables

Snowflake or BYOC

Snowflake credits

dlt

Library, pg_replication source

pgoutput

Load packages

Python

None, dltHub paid

Stitch

Singer tap

wal2json

Vendor managed

SaaS

Rows per month

Debezium

Kafka Connect source

pgoutput

You build the MERGE

Kafka cluster

Kafka to run

PeerDB

Snowflake sink deprecated

pgoutput

Vendor managed

Docker stack

None

Maturity, CDC method, and license come from each tool's docs and LICENSE file. PeerDB still ranks for this route, but its README now says the Snowflake destination is "deprecated and no longer actively maintained."

What are the best ETL tools for PostgreSQL to Snowflake?

The best ETL tools for Postgres to Snowflake in 2026 are Filament, Fivetran, Airbyte, Estuary, and Openflow. All five capture changes through pgoutput logical replication. They differ in where they run, how they bill, and how they prove the copy is right.

  1. Filament fits teams that want verified, resumable change data capture inside their own network with no row or gigabyte meter. Each batch carries a CRC32-C checksum that the Snowflake sink recomputes before the write, per the integrity docs.

  2. Fivetran fits teams that will not run any software. It supports Postgres 10 through 18 and bills on monthly active rows, per its Postgres docs and pricing docs.

  3. Airbyte fits teams that want one open source platform for many sources. Its Snowflake destination writes typed final tables directly since version 4.0, per the destination changelog.

  4. Estuary fits sub-second delivery into Snowflake through Snowpipe Streaming, with a per GB plus per connector bill, per its pricing docs.

  5. Openflow fits teams that want to stay inside Snowflake and already run Apache NiFi, per the Openflow overview.

dlt, Stitch, and Debezium cover narrower cases, and the fit table further down maps each tool to the job it does best.

How to replicate Postgres to Snowflake with Filament

Filament runs the route as one binary with a consistent snapshot bootstrap, sharded parallel reads, checkpointed resume, and per-batch integrity checks, staging Parquet straight into Snowflake. The setup is three commands once the Snowflake role exists. The Postgres source is beta and the Snowflake sink is alpha today, per the sink docs.

Start on the Snowflake side. The sink docs ship the full SQL for a dedicated SERVICE user with key-pair auth, an X-Small warehouse with AUTO_SUSPEND = 60, the database, and the grants. Generate the key with openssl genrsa 2048 piped to pkcs8 -nocrypt.

Then define both ends and the pipeline. Connector fields become CLI flags with a source- or sink- prefix, and underscores become hyphens, per the CLI reference. Confirm the auth flag names with filament sink create --help.

filament source create app-db \
  --source-connector postgres \
  --source-connection-method url \
  --source-dsn-env POSTGRES_DSN \
  --source-replication cdc

filament sink create analytics \
  --sink-connector snowflake \
  --sink-account myorg-myaccount \
  --sink-username FILAMENT_USER \
  --sink-warehouse FILAMENT_WAREHOUSE \
  --sink-database-name FILAMENT_DATABASE \
  --sink-role FILAMENT_ROLE \
  --sink-auth-type key_pair \
  --sink-auth-private-key-env SNOWFLAKE_PRIVATE_KEY

filament pipeline create pg-to-snowflake \
  --source app-db --sink analytics \
  --resources orders,customers \
  --write-mode

filament source create app-db \
  --source-connector postgres \
  --source-connection-method url \
  --source-dsn-env POSTGRES_DSN \
  --source-replication cdc

filament sink create analytics \
  --sink-connector snowflake \
  --sink-account myorg-myaccount \
  --sink-username FILAMENT_USER \
  --sink-warehouse FILAMENT_WAREHOUSE \
  --sink-database-name FILAMENT_DATABASE \
  --sink-role FILAMENT_ROLE \
  --sink-auth-type key_pair \
  --sink-auth-private-key-env SNOWFLAKE_PRIVATE_KEY

filament pipeline create pg-to-snowflake \
  --source app-db --sink analytics \
  --resources orders,customers \
  --write-mode

filament source create app-db \
  --source-connector postgres \
  --source-connection-method url \
  --source-dsn-env POSTGRES_DSN \
  --source-replication cdc

filament sink create analytics \
  --sink-connector snowflake \
  --sink-account myorg-myaccount \
  --sink-username FILAMENT_USER \
  --sink-warehouse FILAMENT_WAREHOUSE \
  --sink-database-name FILAMENT_DATABASE \
  --sink-role FILAMENT_ROLE \
  --sink-auth-type key_pair \
  --sink-auth-private-key-env SNOWFLAKE_PRIVATE_KEY

filament pipeline create pg-to-snowflake \
  --source app-db --sink analytics \
  --resources orders,customers \
  --write-mode

The first run creates the slot with an exported snapshot and reads each table in full through it, "so the baseline and the change stream share one consistent point," per the Postgres source docs. Large tables split into as many as 64 parallel ranges, saved in the checkpoint so a resumed run keeps its read plan. Filament creates the publication itself and keeps its table list current.

Each later run is a bounded catch-up to the current WAL position, so continuous change data capture is a loop you schedule with cron or a Kubernetes job. On the write side, "each Arrow batch is encoded as a Snappy-compressed Parquet file in memory," uploaded with PUT to the user's stage, loaded with COPY INTO, and removed, per the sink docs. No bucket, storage integration, or Kafka sits in between.

Merge mode loads each batch into a temporary table and applies one MERGE, so the Snowflake table holds the current row per primary key rather than a raw event log. Schema evolution is add-only into typed tables, and a failed attempt replays rather than skips.

How do you stream Postgres to Snowflake in near real time?

Near real time on this route means one of two delivery models. Streaming tools push rows through Snowpipe Streaming, which Snowflake says makes data queryable in "as low as 5 seconds," per the Snowpipe Streaming overview. Micro-batch tools run a short catch-up on a schedule and load with COPY INTO and MERGE.

Tool

Delivery model

Fastest cadence

Source

Estuary

Snowpipe Streaming for delta updates

Under 100 ms end to end, vendor claim

Estuary

Openflow

Snowpipe Streaming

Seconds

Openflow Postgres docs

Fivetran

Micro-batch

1 minute on Enterprise and Business Critical

Sync overview

Airbyte Cloud

Micro-batch

5 minutes on Pro, 15 on Plus, 1 hour on Standard

Airbyte pricing

Filament

Micro-batch catch-up

As often as you schedule it

Postgres source docs

Streaming wins when a dashboard or an agent needs rows within seconds. Estuary only uses Snowpipe Streaming for delta-update bindings, per its Snowflake connector docs, so a merged current-state table still runs as micro-batches there. For most analytics, a one to five minute merge is the better trade, because the table holds one clean row per key and the warehouse sleeps between loads.

What are the best practices for near real-time Postgres to Snowflake replication?

These six habits keep a fast pipeline from filling the source disk or the Snowflake bill. They apply to every tool on this list.

  • Cap the slot. With the default max_slot_wal_keep_size of -1, "replication slots may retain an unlimited amount of WAL files," per the replication config docs. Set a ceiling that fits your disk.

  • Watch wal_status and safe_wal_size. The pg_replication_slots view reports both, and an alert on unreserved catches a stalled consumer before the slot is lost.

  • Add a heartbeat on quiet databases. A low-traffic database on a busy host can hold WAL behind an idle slot. Debezium's heartbeat.action.query exists for exactly this case, per its Postgres connector docs.

  • Give every table a primary key. A table "must have a replica identity configured in order to be able to replicate UPDATE and DELETE operations," per the publication docs.

  • Match the cadence to the warehouse. Snowflake bills warehouses "per-second billing (with a 60-second minimum each time the warehouse starts)," per the warehouse docs. A load every 30 seconds keeps the warehouse running all day, so pick the slowest cadence the business accepts.

  • Point at the writer on Aurora. Aurora does not offer logical decoding from read replicas, and Openflow needs Postgres 16 or newer for standby decoding, per the Openflow docs.

Filament covers the first habit on its side of the slot. It advances the slot only after a committed write and refuses to run past a slot another client consumed, so the slot never drifts from what landed in Snowflake.

What are the best Fivetran and Airbyte alternatives for Postgres to Snowflake CDC?

The main alternatives are Filament, Estuary, Openflow, and dlt. Teams usually leave Fivetran over the row meter and leave Airbyte Cloud over sync frequency or credit cost, so the right alternative depends on which of those hurts.

Fivetran has the widest managed Postgres range, 10 through 18. Its query-based fallback replaced the old XMIN method and only detects deleted rows if you enable Capture Deletes, per its Postgres docs. Every active row counts once per month toward the MAR meter, with 500,000 MAR on the free plan, so the bill grows with your tables.

Airbyte is open source, with connectors under the Elastic License 2.0, per its license page. Its certified Postgres source runs change data capture through pgoutput. Airbyte Cloud Standard starts at $20 per month with 5 credits included and extra credits at $5 each, per its pricing page.

  • Filament replaces the meter entirely. It runs on your own host, checksums every batch, and the only bill is Snowflake warehouse time.

  • Estuary replaces batch cadence with streaming. It charges $0.50 per GB plus $100 per month for each of the first six connectors, per its pricing docs.

  • Openflow replaces a third-party vendor with Snowflake itself. It runs on Apache NiFi, and its journal tables "are retained indefinitely and are not automatically cleaned up," per the Openflow Postgres docs.

  • dlt replaces a platform with a Python library. The library stays Apache 2.0, while the managed dltHub tier costs $12,000 per month, per dltHub pricing.

What does the Postgres side need?

Postgres needs wal_level = logical, a replication role, a publication, and a slot, and Filament manages the last two for you. The four settings are the same for every tool.

  • Set wal_level to logical, which "can only be set at server start," per the Postgres WAL config docs.

  • Give the connecting role the REPLICATION attribute, per the logical replication security docs.

  • Give every replicated table a primary key so updates and deletes can be matched.

  • On RDS and Aurora, set rds.logical_replication to 1 and reboot the writer, per the Aurora docs.

How do Postgres types land in Snowflake?

Most types map cleanly, but zoned timestamps differ by tool, so check the mapping before building dashboards on the copy.

Postgres

Filament

Openflow

Note

integer, bigint

NUMBER(38,0)

NUMBER

Same

numeric

NUMBER(p,s) up to 38

NUMBER

Snowflake's 38 digit ceiling

timestamp

TIMESTAMP_NTZ(6)

TIMESTAMP_NTZ

Wall clock, no zone

timestamptz

TIMESTAMP_TZ(6)

TIMESTAMP_LTZ

Fivetran and Airbyte use TZ

jsonb

VARIANT

VARIANT

Openflow caps values at 16 MB by default

uuid, array

TEXT

TEXT

Same in both

Mappings come from the Filament sink docs and the Openflow data mapping page. Snowflake's TIMESTAMP_TZ "only stores the offset of a given time zone, not the actual time zone," per the datetime docs, so Filament's choice keeps the offset your app wrote.

TOAST columns need one setting. Filament asks for REPLICA IDENTITY FULL on tables with large text or JSON values, while Openflow substitutes a placeholder your MERGE has to special-case.

Which tool fits which job?

No public benchmark covers this route, so speed is not a column here. On the one route with a public run, Postgres to Postgres, Filament moved 298M rows in 115 s and led every other tool, per the seven-tool benchmark. The same engine drives the Snowflake sink.

Tool

Best for

Trade-off

Cost

Filament

Verified, resumable CDC inside your network

Newest sink in its catalog

No meter, warehouse seconds only

Fivetran

Teams that will not run any software

MAR bill grows with rows

MAR, 500k free

Airbyte

One open source platform for many sources

Hourly syncs on Cloud Standard

From $20 per month plus credits

Estuary

Snowpipe Streaming delivery

BSL license, per-connector fee

$0.50 per GB plus $100 per connector

Openflow

Staying inside Snowflake

NiFi cluster, journal tables never auto-clean

Snowflake credits

dlt

Python pipelines as code

Build your own scheduling and checks

Free library, dltHub $12,000 per month

Stitch

Simple row-based billing

Needs wal2json installed

From $100 per month

Debezium

Already running Kafka

Lands VARIANT, you write the MERGE

Kafka to run

Which Postgres to Snowflake tool should you pick?

For most teams the choice comes down to correctness, control, cost, and freshness. If the constraint is correctness, Filament checksums every batch on both sides of the write and bootstraps change data capture from a single consistent snapshot. If it is control, Filament runs as one binary or a Go library inside your network, with no data leaving through a vendor.

If the constraint is cost at scale, every managed tool meters rows, gigabytes, or credits while Filament has no meter. The only bill is the Snowflake warehouse, and a one to five minute cadence with AUTO_SUSPEND keeps it small. If the constraint is sub-second freshness on an append-only feed, Estuary's Snowpipe Streaming path is built for it.

The narrow cases go elsewhere. A team that will not run any software should look at Fivetran, and a shop already committed to NiFi inside Snowflake can use Openflow. Galaxy, which maintains Filament, publishes the connector maturity table and the benchmark harness in the open, so every claim above can be checked.

Related routes in this series cover MySQL to Snowflake, Postgres to ClickHouse, Postgres logical replication, the best change data capture tools, and the data movement tool roundup.

Frequently asked questions

What are the best ETL tools for PostgreSQL to Snowflake?

Filament, Fivetran, Airbyte, Estuary, and Snowflake Openflow are the main options in 2026, and all five capture changes through pgoutput logical replication. Filament runs inside your network and checksums every batch. Fivetran is fully managed and bills monthly active rows. Airbyte is open source with a credit-based cloud. Estuary streams through Snowpipe Streaming. Openflow runs inside Snowflake on Apache NiFi.

What is the best way to replicate Postgres to Snowflake?

Run logical replication change data capture through pgoutput, seed each table from one consistent snapshot, and MERGE changes into typed tables. Filament does all three from one binary. It verifies each batch with a CRC32-C checksum, checkpoints so a failure resumes rather than restarts, and stages Parquet straight into Snowflake with no external bucket.

How do I stream Postgres to Snowflake in near real time?

Pick a delivery model first. Snowpipe Streaming tools such as Estuary and Openflow make rows queryable within seconds. Micro-batch tools such as Filament, Fivetran, and Airbyte merge changes on a schedule, from one minute upward. For most analytics a one to five minute merge is the better trade, because the table keeps one current row per key and the warehouse can suspend between loads.

What are the best Fivetran alternatives for Postgres to Snowflake CDC?

Filament, Estuary, Openflow, and dlt. Filament removes the row meter and runs on your own host. Estuary adds sub-second streaming for a per GB and per connector fee. Openflow keeps the pipeline inside Snowflake. dlt turns the pipeline into Python code you schedule yourself.

How does Filament write to Snowflake?

Each batch is encoded as a Snappy Parquet file in memory, uploaded with PUT to the user's internal stage, loaded with COPY INTO, and removed. Merge mode loads the batch into a temporary table and applies one MERGE, so the Snowflake table always holds the current row per primary key. No storage integration, bucket, or Kafka is needed.

Does Snowflake have a native Postgres connector?

Openflow Connector for PostgreSQL is Snowflake's current option. It runs on Apache NiFi, supports Postgres 11 through 18, and loads through Snowpipe Streaming. Its journal tables are kept indefinitely, so plan a cleanup job.

What does Postgres need for CDC to Snowflake?

Set wal_level to logical, which needs a server restart, and give the replication user the REPLICATION attribute. Every replicated table needs a primary key so updates and deletes can be matched. On RDS and Aurora, set rds.logical_replication to 1 and reboot. Filament creates the publication and the replication slot itself and keeps the table list current.

Is Filament faster than Fivetran or Airbyte for Postgres to Snowflake?

No public benchmark covers this route yet, so no tool can claim it. On the one route with a public run, Postgres to Postgres, Filament moved 298 million rows in 115 seconds and finished ahead of every other tool measured. The same engine, sharded reads, and batch pipeline drive the Snowflake sink.

How much does Postgres to Snowflake replication cost?

Two bills apply. Fivetran meters monthly active rows, Airbyte Cloud bills credits, Estuary meters gigabytes plus connectors, and Stitch meters rows, so the tool bill grows with your data. Filament runs on your own host with no meter. Snowflake then bills warehouse seconds for each load, with a 60 second minimum each time the warehouse starts.

How are Postgres types mapped to Snowflake?

Integers become NUMBER(38,0), numerics keep precision up to 38 digits, timestamps without zone become TIMESTAMP_NTZ, JSONB becomes VARIANT, and UUIDs become TEXT. Timestamps with zone differ by tool, since Filament and Fivetran use TIMESTAMP_TZ while Openflow uses TIMESTAMP_LTZ. Filament creates typed tables and adds new columns automatically.

Can I replicate from an Aurora or RDS read replica?

Not on Aurora, because Aurora does not offer logical decoding from read replicas. Openflow and Fivetran both need Postgres 16 or newer to decode from a standby. Point every tool, Filament included, at the writer instance.

More articles

Stay up to date with what weโ€™re building

Stay up to date with what weโ€™re building

Stay up to date with what weโ€™re building

Questions

Answered

FAQ

What does Galaxy do?

What is Filament?

What is enterprise context management?

What does working with Galaxy look like?

How do you handle security and compliance?

Why does Galaxy build in the open?

Own your knowledge stack

Own your knowledge stack

Copyright ยฉ 2026 Galaxy. All rights reserved.