apps/docs/content/guides/database/replication/pipelines.mdx
<$Partial path="pipelines-public-alpha.mdx" />
Supabase Pipelines is a managed CDC product for moving data from Supabase Postgres to supported destination systems. It uses Postgres logical replication with the open-source Supabase ETL engine. You choose a destination in the Dashboard, and Supabase runs the pipeline that sends database changes to that destination.
Pipelines has two replication phases:
Managed Pipelines run in AWS eu-central-1 (Frankfurt). Choose a destination region as close as possible to Frankfurt to reduce network latency and replication lag.
<$Partial path="billing/pricing/pricing_pipelines.mdx" />
For billing examples and optimization guidance, see Manage Pipelines usage.
Pipelines requires two main components: a Postgres publication (defines what to replicate) and a destination (where data is sent). Supabase runs the managed pipeline that reads from the publication and writes to the destination. Follow these steps to set up your replication pipeline.
<Admonition type="note">If you already have a Postgres publication set up, you can skip to Step 2: Enable Pipelines.
</Admonition>A Postgres publication defines which tables and change types will be replicated from your database. You can create a basic publication in the Dashboard while configuring the destination, or use SQL when you need column lists, row filters, schema-wide publications, or other advanced options.
The following SQL examples assume you have users and orders tables in your database.
-- Create publication for both tables
create publication pub_users_orders
for table users, orders;
This publication tracks all changes (INSERT, UPDATE, DELETE, TRUNCATE) for both the users and orders tables.
-- Create a publication for all tables in the public schema
create publication pub_all_public for tables in schema public;
This tracks changes for all existing and future tables in the public schema.
-- Create a publication for all tables
create publication pub_all_tables for all tables;
This tracks changes for all tables in your database.
<Admonition type="caution">FOR ALL TABLES includes tables in Supabase-managed schemas, including the internal etl tables that Pipelines creates. Prefer FOR TABLES IN SCHEMA public or list the application tables explicitly unless you intend to replicate every eligible table in the database.
You can replicate only a subset of columns from a table:
-- Replicate only specific columns from the users table
create publication pub_users_subset
for table users (id, email, created_at);
This only replicates the id, email, and created_at columns from the users table.
You can filter which rows to replicate using a WHERE clause:
-- Only replicate active users
create publication pub_active_users
for table users where (status = 'active');
-- Only replicate recent orders
create publication pub_recent_orders
for table orders where (created_at > '2024-01-01');
Pipelines follows Postgres publication semantics for partitioned tables. The publish_via_partition_root publication setting controls whether changes from partitions are emitted as the partition root or as the leaf partitions.
| Publication setting | What gets replicated | Destination shape |
|---|---|---|
publish_via_partition_root = true | Rows from the published partition root, including rows stored in its leaf partitions | One table matching the published partition root |
publish_via_partition_root = false | Rows from the leaf partitions under the published partition root | One table per replicated leaf partition |
| Not set in SQL | Same as false, because Postgres defaults publish_via_partition_root to false | One table per replicated leaf partition |
| Publishing an individual leaf partition | The leaf partition itself, regardless of publish_via_partition_root | One table for that leaf partition |
FOR ALL TABLES or FOR TABLES IN SCHEMA | Partition roots plus regular tables when true; leaf partitions plus regular tables when false or unset | Destination tables follow the effective Postgres publication table list |
For example, if orders is partitioned by month:
-- Replicate the whole partition hierarchy as the parent table.
create publication pub_orders_root
for table orders
with (publish_via_partition_root = true);
-- Replicate each leaf partition as its own table.
create publication pub_orders_leaves
for table orders
with (publish_via_partition_root = false);
Use publish_via_partition_root = true when you want analytics queries to read from a single destination table that has the parent table's schema. Use false when each partition should remain a separate destination table.
Publications created from the Dashboard replication flow use publish_via_partition_root = true. If you create or alter a publication manually with SQL, set this option explicitly so the destination shape matches what you expect.
On Postgres 15 and newer, row filters on partition publications apply during both the initial sync and ongoing replication. Pipelines uses the row filter attached to the effective publication table entry: the published partition root when publish_via_partition_root = true, and the published leaf relation when publish_via_partition_root = false.
The publication setting controls which Postgres relation becomes a destination table. It does not copy the source table's physical partitioning configuration, partition key, or partition bounds to BigQuery.
<Admonition type="note">With publish_via_partition_root = true, truncating an individual leaf partition is not replicated as a truncate event for the published parent. This is useful for append-only data such as events: you can truncate old leaf partitions to keep Postgres storage bounded while retaining the rows already copied to the destination. If you want the destination to be truncated too, run TRUNCATE on the published partition root.
Rows retained only in the destination aren't a permanent archive. A table reset or full pipeline initial sync rebuilds the destination from the rows that still exist in Postgres.
</Admonition>After creating a publication via SQL, you can view it in the Dashboard:
Before creating a managed replication pipeline, enable Pipelines for your project:
Once Pipelines is enabled and you have a Postgres publication, configure a destination. The destination is where your replicated data will be stored, while the pipeline is the active Postgres replication process that continuously streams changes from your database to that destination.
Follow these steps to configure your destination. Each destination has its own setup requirements and behavior. BigQuery is currently available. You can request early access to ClickHouse, Snowflake, and DuckLake.
Navigate to the Database > Replication section of the Dashboard
Click Add destination if the destination side panel isn't already open
Select the destination type
Configure the destination details:
eu-central-1 (Frankfurt) region. This can't be changed. In your destination provider, choose a nearby dataset, warehouse, or storage bucket region.Configure the destination-specific settings. See the destination guide for required credentials, permissions, and limitations:
Optionally expand Advanced settings to tune pipeline behavior:
| Setting | Default | Allowed values | Description |
|---|---|---|---|
| Batch wait time | 10000 milliseconds | Whole milliseconds, 0 or greater | Maximum time after the first buffered initial-sync row or ongoing change before the pipeline flushes a partially filled batch. Internal size and memory limits can flush it earlier. Lower values can reduce batching delay; higher values can improve destination write efficiency. |
| Table sync workers | 4 workers | Whole number greater than 0 | Maximum number of tables synced in parallel during the initial sync. Each active table sync temporarily uses one additional replication slot, up to N + 1 slots including the pipeline's main slot. |
| Copy connections per table | 4 connections | Whole number greater than 0 | Maximum source database connections used to copy one table in parallel. With multiple table sync workers, source connection usage can scale with both settings. More connections can speed up large tables until the source database, network, or destination becomes the bottleneck. |
| Invalidated slot behavior | Error | Error or Recreate | What happens when the main replication slot can no longer continue from retained WAL. Error blocks startup for manual recovery. Recreate resets table sync state, rebuilds the slot on the next start, and runs the initial sync again for every replicated table. |
Leave these settings at their defaults unless you need to tune initial sync speed, latency, or recovery behavior.
Use Invalidated slot behavior carefully. If Recreate is selected and the pipeline starts after Postgres has invalidated the main replication slot, the pipeline resets its saved table-sync state, creates a new slot, and replaces each destination table through a new initial sync. This destructive restart is required for consistency because the old slot can no longer provide every change the pipeline missed, and the data processed during the new initial sync is billed again.
Click Create and start pipeline to begin replication
<Image alt="Pipeline cost confirmation showing the initial sync estimate and ongoing replication prices" caption="Review the estimated initial sync cost and the separate ongoing charges before creating the pipeline." src="/docs/img/database/replication/pipelines-cost-confirmation.png" width={5080} height={2716} zoomable />
The pipeline begins the initial sync from your database to your destination.
After you create and start the pipeline, its destination appears in the destinations list. You can monitor the pipeline's status and performance from the Dashboard.
For comprehensive monitoring instructions including pipeline states, metrics, and logs, see Monitor pipeline status.
You can manage your pipeline from the destinations list using the actions menu.
<Image alt="Destinations list with the actions menu open for a running BigQuery pipeline" caption="Use the actions menu to update, restart, stop, edit, or delete a pipeline destination." src="/docs/img/database/replication/pipelines-actions-menu.png" width={5080} height={2716} zoomable />
Available actions:
To turn off Pipelines for a project, delete all Pipelines destinations first. After all destinations are removed, open the three-dot actions menu on the Replication page and click Disable Pipelines.
For cleanup details, see What happens when you disable Pipelines?.
If you need to modify which tables are replicated after your replication pipeline is already running, follow these steps:
<Admonition type="note">If your Postgres publication uses FOR ALL TABLES or FOR TABLES IN SCHEMA, new tables in that scope are automatically included in the publication. However, you still must restart the replication pipeline for the changes to take effect.
Add the table to your publication using SQL:
-- Add a single table to an existing publication
alter publication pub_users_orders add table products;
-- Or add multiple tables at once
alter publication pub_users_orders add table products, categories;
Restart the replication pipeline using the actions menu (see Managing your pipeline) for the changes to take effect.
Remove the table from your Postgres publication using SQL:
-- Remove a single table from a publication
alter publication pub_users_orders drop table orders;
-- Or remove multiple tables at once
alter publication pub_users_orders drop table orders, products;
Restart the replication pipeline using the actions menu (see Managing your pipeline) for the changes to take effect.
When a table is deleted at the destination, the behavior depends on the destination. In general, the pipeline tries to recreate the table so replication can continue. To permanently delete a table, stop the pipeline first or remove it from the publication before deleting. See the Pipelines FAQ for details.
</Admonition>Schema change support depends on the destination. BigQuery is currently the only destination with beta schema change support. See BigQuery schema change support for supported and unsupported changes.
Once configured, a replication pipeline:
Pipelines automatically optimizes how changes are delivered to the destination. It maps published source columns and values to destination-compatible names and types, but doesn't provide user-defined transformations.
If you encounter issues during setup:
For more troubleshooting help, see the Pipelines FAQ.
Pipelines has the following limitations:
Destination-specific limitations, such as BigQuery's row size limits, are documented in each destination guide.