Postgres to Snowflake: The Complete Replication Guide

Intergalactic Data Labs
—
—
10 min read
The best way to replicate Postgres to Snowflake in 2026 is logical replication CDC through pgoutput, run with Filament. It bootstraps each table from one exported snapshot, verifies every batch with a CRC32-C checksum, and resumes from checkpoints, all from one binary inside your own network. Fivetran, Airbyte, Estuary, and Openflow run the same route with a meter, a hosted model, or a NiFi cluster attached.
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 xmin | Vendor managed | SaaS | Monthly active rows |
Airbyte | Certified source, dest v5 | pgoutput via Debezium or xmin | Raw plus final tables | OSS or Cloud | Per GB 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 plus | pgoutput, Snowpipe Streaming | Journal tables | Snowflake or BYOC | Snowflake credits |
dlt | Library, pg_replication source | pgoutput | Load packages | Python | None, dltHub paid |
Stitch | Released 2021, Singer tap | wal2json | Vendor managed | SaaS | Rows per month |
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 calls the Snowflake destination "deprecated and no longer actively maintained."
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, and the Postgres source is beta with the Snowflake sink at alpha today, per its 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. The docs' worked examples use Postgres and stdout sinks, so the Snowflake flags below follow that rule and the sink's config table. Confirm the auth flag names with filament sink create --help.
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 CDC 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. Before that write, the pipeline computes a CRC32-C checksum over the batch and the sink recomputes it at its boundary, per the integrity docs. Schema evolution is add-only into typed tables, and a failed attempt replays rather than skips.
How do Fivetran, Airbyte, Estuary, and Openflow run the same route?
All four use pgoutput logical replication, and each attaches something Filament does not need. That extra is a row meter, a raw table layer, a per-connector fee, or a NiFi cluster.
Fivetran has the widest managed Postgres range, 10 through 18, and recommends logical replication "if you have a large database," per its Postgres docs. Its query-based fallback uses xmin and "does not preserve details about deleted rows." Every synced row counts toward the monthly active rows meter, per its pricing page, so the bill grows with your tables.
Airbyte's certified Postgres source offers CDC through Debezium, xmin, or a user cursor, per its source docs. Its Snowflake destination writes each stream into a raw table plus a typed final table, per its docs. Cloud bills databases at $10 per GB, and the platform is ELv2 rather than Apache 2.0.
Estuary captures with pgoutput plus a watermarks table it writes into your database, and its Snowflake materialization supports Snowpipe Streaming, per the Estuary docs. It is priced per GB plus a fee per connector, per its pricing page, under BSL 1.1.
Openflow is Snowflake's replacement for its own native app connector, which Snowflake says is "not on our product roadmap" for general availability, per the connector docs. Openflow runs on Apache NiFi, loads through Snowpipe Streaming, and writes journal tables that "are retained indefinitely and are not automatically cleaned up," per the Openflow Postgres docs.
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_leveltological, which "can only be set at server start," per the Postgres WAL config docs.Give the connecting role the
REPLICATIONattribute, per the logical replication security docs.Give every replicated table a primary key, since a table "must have a replica identity configured in order to be able to replicate UPDATE and DELETE operations," per the publication docs.
On RDS and Aurora, set
rds.logical_replicationto 1 and reboot the writer, per the Aurora docs.
The slot risk is disk. 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. Filament advances its slot only after a committed write and refuses to run past a slot another client consumed, so the slot never silently diverges from what landed in Snowflake.
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, xmin drops deletes | MAR, 500k free |
Airbyte | Broadest connector catalog | Raw plus final tables, ELv2 | $10 per GB on Cloud |
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 | dltHub from $11,900 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?
Pick by the constraint that breaks first. If the constraint is correctness, Filament checksums every batch on both sides of the write and bootstraps CDC from a single consistent snapshot, per its docs. 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 or gigabytes while Filament has no meter. The only bill is the Snowflake warehouse, "billed per-second, with a 60-second minimum," per the Snowflake cost docs. If it is latency, Filament's catch-up cycle runs as often as you schedule 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 Postgres to ClickHouse, the database replication guide, and the data movement tool roundup.
Frequently asked questions
What is the best way to replicate Postgres to Snowflake?
Run logical replication CDC through pgoutput with Filament. It bootstraps every table from one exported snapshot so the baseline and the change stream share a consistent point. 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 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?
Snowflake has three. The Snowflake Connector for PostgreSQL is a preview native app that Snowflake says will not reach general availability. Openflow Connector for PostgreSQL is its replacement, built on Apache NiFi and loading through Snowpipe Streaming. Snowflake Postgres data mirroring is a preview that only works when the source is a Snowflake Postgres instance.
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 and Estuary meter gigabytes, 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 COPY INTO and MERGE, so set the loading warehouse to auto suspend after 60 seconds.
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, per AWS. Openflow requires Postgres 16 or newer for standby decoding and rules Aurora out for the same reason. Snowflake's native app connector must connect to the primary. Point every tool, Filament included, at the writer instance.
More articles
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?
Company
Talk to the team
Copyright © 2026 Galaxy. All rights reserved.