DevOps Cloud AWS

Why PGOUTPUT Beats PGLOGICAL For Supabase Migrations

If you're migrating a PostgreSQL database hosted on Supabase using AWS DMS, pglogical will fail immediately — Supabase doesn't grant superuser. Here's why pgoutput is the right protocol for this setup, and exactly how to configure it.

DA

Damilare Adekunle

· 4 min read

0 Comments

Short link: https://ddadekunle.com/p/4

Why PGOUTPUT Beats PGLOGICAL For Supabase Migrations

When I was setting up AWS DMS to migrate a production PostgreSQL database off Supabase, the first replication task failed within seconds.

DMS tried to install its audit infrastructure, hit a permission error, and aborted. The error pointed to pglogical — the default plugin DMS reaches for on PostgreSQL sources.

The fix was switching to pgoutput. But to understand why pgoutput is the right choice here — and not just a workaround — it helps to understand what each plugin is actually doing.

What pglogical requires

pglogical is a third-party logical replication extension for PostgreSQL. DMS uses it to capture DDL events on the source database. When DMS initialises a PostgreSQL source endpoint with pglogical, it does two things automatically:

  1. Installs the pglogical extension on the source database
  2. Creates DDL event triggers to capture schema changes during replication

Both of these operations require superuser privileges. You can't install extensions or create event triggers without them.

On a self-managed PostgreSQL instance, this is fine — you control the superuser. On a managed service like Supabase, it's a hard blocker. Supabase doesn't grant superuser. The platform controls the database at that level, and there's no way around it.

What pgoutput actually is

pgoutput is not a third-party extension. It's PostgreSQL's native logical replication protocol, built into the engine since version 10. It was added specifically to support the PUBLICATION / SUBSCRIPTION model introduced in that release.

Because it's part of the PostgreSQL core, pgoutput doesn't require any extension installation. There are no DDL triggers to attach. The protocol works entirely through the Write-Ahead Log (WAL) and a publication you create yourself.

This is the key insight: pgoutput doesn't need anything that requires elevated privileges. Everything it needs, you can create with a normal replication-capable role.

How to configure it

Three things need to exist on the source before DMS can use pgoutput:

A publication. This tells PostgreSQL which tables to include in the replication stream.

CREATE PUBLICATION migration_pub FOR ALL TABLES;

If you only want specific tables, you can name them explicitly. For a full migration, FOR ALL TABLES is fine.

A replication user. This role needs the REPLICATION attribute and SELECT on the tables being replicated. No superuser required.

CREATE ROLE replication_user WITH REPLICATION LOGIN PASSWORD '...';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO replication_user;

A pre-created replication slot. DMS will try to create one itself during setup, but on Supabase, slot creation through the pglogical path fails. Pre-creating the slot manually using pgoutput means DMS attaches to an existing slot rather than trying to provision one:

SELECT pg_create_logical_replication_slot('dms_slot', 'pgoutput');

Once these three exist, you configure the DMS source endpoint to use pgoutput by setting the PluginName parameter to pgoutput in the endpoint's PostgreSQL settings, and point it at your pre-created slot.

One more setting: DDL capture

By default, DMS tries to capture DDL events regardless of the replication plugin. For a one-time migration where the schema is already created on the target, this is unnecessary — and with pgoutput it will cause errors anyway, since there are no DDL event triggers.

Set CaptureDdls=false in the task settings. Schema replication isn't needed; you're migrating rows, not structure.

When you'd still choose pglogical

pgoutput is the right choice for this specific scenario: a one-time migration from a managed PostgreSQL source where superuser isn't available. For ongoing replication setups where you need more control — filtering columns, transforming data in-flight, handling multi-master topologies — pglogical has more advanced features. But on Supabase, it's not an option regardless.

If you're migrating from a self-managed PostgreSQL instance and have superuser access, both plugins work. I'd still lean toward pgoutput for its simplicity: no extension dependency, easier to reason about, and nothing to clean up on the source after the migration completes.

The result

Switching to pgoutput on a Supabase source means:

  • No extension installation required
  • No DDL triggers attached to the source
  • No superuser privileges needed at any point
  • Clean, auditable configuration you create yourself

The replication slot, publication, and replication user are all first-class PostgreSQL objects you own. If something breaks, you can inspect and fix it directly. That's a better position to be in than depending on DMS to set things up for you — especially on a platform where it can't.

Share

Twitter LinkedIn

Comments (0)

Comments are protected by anti-spam filters and rate limiting.

No comments yet. Start the discussion.