pgoutput logical replication stream from a slot it creates for the
pipeline, snapshots each table through the same consistent point, and merges
inserts, updates, and deletes into typed Snowflake tables. Data is staged as
Parquet in the Snowflake user’s internal stage. Each run is a bounded catch-up
from the last durable position to the current WAL position, so you schedule
runs as often as you need fresh data.
The PostgreSQL source is beta and
the Snowflake sink is alpha.
How it works
- Snapshot. The first run creates a replication slot with an exported snapshot and reads every selected table through it.
- Catch up. Later runs replay changes from the slot up to the current WAL position and stop. A run with no changes still saves the position.
- Merge.
mergewrites upsert inserts and updates by primary key and delete removed rows, so Snowflake mirrors PostgreSQL.
Prerequisites
- PostgreSQL with
wal_level=logical, and a primary key on every replicated table - A Snowflake account where you can create a role, warehouse, database, and user
- A Filament deployment backed by the PostgreSQL datastore, with the CLI
pointed at it through
filament context addandfilament context use
CDC needs a datastore that can durably track replication streams. The local
CLI context stores state in SQLite and rejects CDC pipelines with
cannot durably admit replication streams. Deploy Filament on
Kubernetes,
Railway, or
Render, or run the PostgreSQL-backed stack
from Local development to try
it on a laptop.1. Prepare PostgreSQL
Enable logical replication and restart PostgreSQL. On RDS, Cloud SQL, or Azure, set the equivalent parameter on the instance instead.create publication "filament": ERROR: permission denied. Creating the
publication yourself and setting manage_publication to false (step 3)
avoids granting Filament ownership of your tables.
For tables with large text, jsonb, or bytea values that change without
being rewritten, set full replica identity:
2. Prepare Snowflake
Generate a key pair for the service user:FILAMENT_ROLE owns it and can
create and evolve tables there. The full grant reference is on the
Snowflake sink page.
3. Create the source and sink
--sink-account takes the organization-account identifier. On a deployed
server, secret values such as the DSN and private key are stored by the
deployment’s secret provider.
4. Create the pipeline and run the snapshot
--sync-mode cdc explicitly. Without it the CLI fills in the default read
mode, and a CDC source rejects it with
pipeline graph is invalid: CDC connections do not accept a read mode.
The first run snapshots every selected table. In the test database, that was
1,100,500 rows across customers and orders.
5. Catch up on changes
Make changes in PostgreSQL:6. Verify
_filament_run_id,
_filament_run_started_at, _filament_operation,
_filament_source_position, and _filament_sequence.
On the source, check replication slot lag:
7. Schedule it
Add a cron schedule to the pipeline in the web app or with the Pipelines API. Every 5 to 15 minutes is common. The Snowflake warehouse resumes for each load and suspends afterAUTO_SUSPEND, so the schedule drives most of the Snowflake compute cost.
Going to production
- Slot lag: an unread slot keeps WAL on the source disk. Keep the schedule
running, and drop slots for pipelines you delete. Filament stores each
generated slot name in the control database’s
replication_streams.consumer_namecolumn. - Start without a snapshot:
--source-snapshot-mode noneon the pipeline streams from the current position, and the destination fills in as rows change. - History instead of a mirror:
--write-mode appendkeeps every change as a row, with deletes as events. - Schema changes: new columns are added to Snowflake tables. Renames, type changes, and dropped columns are not applied automatically.
Troubleshooting
create publication "filament": ERROR: permission denied
The replication user cannot create publications. Create the publication as a
table owner and set --source-manage-publication=false.
CDC connections do not accept a read mode
Add --sync-mode cdc to filament pipeline create.
261004 (08004): failed to auth for unknown reason. HTTP: 404
The Snowflake account identifier is wrong. Use the organization-account form
shown in Snowsight under your account details.
slot is active
Another client holds the pipeline’s replication slot. Stop that consumer or
wait for the previous run to finish.
More errors are in Troubleshooting.
FAQ
Does Filament replicate deletes from PostgreSQL to Snowflake?
Yes. CDC captures deletes from the WAL, andmerge removes those rows in
Snowflake.
Is the replication continuous?
Each run catches up to the WAL position at the moment it starts and then stops. Scheduling runs every few minutes gives near-continuous replication without a warehouse that stays running.Can I replicate tables without a primary key?
Not with CDC. Copy keyless tables with a separate full replace pipeline.Does Filament need superuser access to PostgreSQL?
No. It needs a role withREPLICATION and SELECT on the tables, plus a
publication created by a table owner.