{
  "id": "supabase",
  "title": "Prepare Supabase for RDI",
  "url": "https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/supabase/",
  "summary": "Prepare a hosted Supabase database to work with RDI",
  "tags": [
    "docs",
    "integrate",
    "rs",
    "rdi"
  ],
  "last_updated": "2026-08-03T16:20:47+02:00",
  "page_type": "content",
  "content_hash": "da3ee3ee4b1d52d6a65f8041c96166d70f2212bd4fcebf4bf29782c05c1fc66f",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "[Supabase](https://supabase.com/docs/guides/database/overview) is a hosted\nPostgreSQL platform. RDI can connect to a hosted Supabase project\nthrough any direct PostgreSQL endpoint as long as it is reachable from the RDI\ndeployment and supports logical replication.\n\n\nRDI supports hosted Supabase projects running an\n[RDI-supported PostgreSQL version](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs).\nThe integration was validated with RDI 1.19.0 and hosted Supabase PostgreSQL\n17.6. For self-hosted Supabase deployments, follow the general\n[PostgreSQL preparation guide](https://redis.io/docs/latest/integrate/redis-data-integration/data-pipelines/prepare-dbs/postgresql).\nThis page describes Supabase setup for a self-managed RDI deployment. For the\nmanaged service, see\n[Use Supabase with RDI on Redis Cloud](https://redis.io/docs/latest/operate/rc/rdi/supabase).\n\n\nSupabase differs from a typical self-managed PostgreSQL source in the following\nways:\n\n- You can't edit `postgresql.conf` or `pg_hba.conf` directly. Supabase enables\n  logical replication and manages these settings for you.\n- You must use the direct database endpoint for logical replication because\n  [Supavisor connection pooler endpoints don't support logical replication](https://supabase.com/docs/guides/database/replication/manual-replication-faq#which-connection-string-should-be-used).\n- The direct endpoint uses IPv6 unless you enable the Supabase dedicated IPv4\n  add-on. Enable the add-on if your RDI deployment can't connect over IPv6.\n- Supabase can enforce TLS and provides a CA certificate that RDI can use to\n  validate the database certificate.\n- Supabase Row Level Security (RLS) can restrict the rows visible during the\n  initial snapshot.\n\nThe following checklist summarizes the setup:\n\n[code example]"
    },
    {
      "id": "1-create-or-select-a-supabase-project",
      "title": "1. Create or select a Supabase project",
      "role": "content",
      "text": "Create a project in the [Supabase dashboard](https://supabase.com/dashboard)\nor select an existing project. You can find its PostgreSQL version in the\nSupabase dashboard or run the following query in the SQL editor:\n\n[code example]"
    },
    {
      "id": "2-configure-direct-network-access",
      "title": "2. Configure direct network access",
      "role": "content",
      "text": "For a public connection, select **Connect** in the Supabase dashboard and copy\nthe **Direct connection** hostname. It has the following form:\n\n[code example]\n\nYou should generally use port `5432`, but you can use a private hostname or\naddress instead if you have configured private connectivity between the RDI\ndeployment and Supabase.\nDon't use a Supavisor transaction or session pooler connection string because\nthese endpoints don't support logical replication.\n\nSupabase direct connections use IPv6 by default. If your RDI deployment\ndoesn't have IPv6 egress, enable the\n[dedicated IPv4 add-on](https://supabase.com/docs/guides/platform/ipv4-address).\nThe add-on requires a paid Supabase plan.\n\nIf you use the public endpoint and enable\n[Supabase Network Restrictions](https://supabase.com/docs/guides/platform/network-restrictions),\nadd the public egress address of the RDI host or cluster to the allowlist. Use\na `/32` CIDR for an individual IPv4 address. For private connectivity, make\nsure the RDI host or cluster can resolve and route to the private endpoint."
    },
    {
      "id": "3-create-a-dedicated-rdi-role",
      "title": "3. Create a dedicated RDI role",
      "role": "content",
      "text": "In the Supabase SQL editor, create a dedicated login for RDI. Replace the\nexample name and password with your own values:\n\n[code example]\n\n\nDon't use the Supabase `postgres` administrator account for the RDI connection.\nThe RDI role's credentials provide continuous access to captured data, so grant\nthe role only the permissions it needs."
    },
    {
      "id": "4-grant-access-to-source-tables",
      "title": "4. Grant access to source tables",
      "role": "content",
      "text": "The RDI role needs to connect to the database and read every table included in\nthe initial snapshot. For example:\n\n[code example]\n\nRepeat the schema grants for every schema you want RDI to capture.\n\nIf RLS is enabled on a source table, the initial snapshot only contains rows\nvisible to the RDI role. To capture all rows, define appropriate RLS policies\nfor the role or grant `BYPASSRLS`:\n\n[code example]\n\n`BYPASSRLS` applies to every table in the database. Grant it only to a\ndedicated RDI role and protect that role's credentials."
    },
    {
      "id": "create-a-publication",
      "title": "Create a publication",
      "role": "content",
      "text": "By default, RDI uses the PostgreSQL `pgoutput` logical decoding plug-in, a\npublication named `dbz_publication`, and a replication slot named `debezium`.\nThese defaults work with Supabase if the RDI role has permission to create the\npublication and manage its source tables.\n\nIt is recommended that a database administrator create a publication\ncontaining only the tables RDI should capture:\n\n[code example]\n\nCreating the publication explicitly avoids granting table ownership or broad\npublication-creation permissions to the RDI role and limits the publication's\ntable scope."
    },
    {
      "id": "5-configure-tls",
      "title": "5. Configure TLS",
      "role": "content",
      "text": "In the Supabase dashboard, go to\n[**Database settings** > **SSL configuration**](https://supabase.com/docs/guides/platform/ssl-enforcement):\n\n1. Enable **Enforce SSL on incoming connections**.\n1. Download the Supabase CA certificate.\n\nStore the database username, password, and CA certificate as RDI secrets:\n\n[code example]\n\nRDI verifies that the direct endpoint hostname matches the certificate."
    },
    {
      "id": "6-configure-rdi",
      "title": "6. Configure RDI",
      "role": "content",
      "text": "Add a PostgreSQL source to `config.yaml`. Replace the project reference and\ntable names with your values:\n\n[code example]\n\nUse a unique replication slot name for each active pipeline that connects to\nthe project."
    },
    {
      "id": "7-monitor-replication-slots",
      "title": "7. Monitor replication slots",
      "role": "content",
      "text": "RDI creates a logical replication slot that retains write-ahead log (WAL)\nrecords while the pipeline is stopped or disconnected. Use a query like the\nfollowing to monitor inactive slots and retained WAL to prevent unexpected\nstorage growth:\n\n[code example]\n\n[Supabase requires logical replication slots to be removed](https://supabase.com/docs/guides/platform/upgrading)\nbefore a PostgreSQL major-version upgrade. Before upgrading:\n\n1. Stop the RDI pipeline.\n1. Record the pipeline configuration and slot name.\n1. Drop the RDI replication slot.\n1. Upgrade the Supabase project.\n1. Reset and start the RDI pipeline to create a new slot and initial snapshot.\n\nAllow time for the new initial snapshot to complete, and monitor the pipeline\nuntil pending records return to zero."
    }
  ],
  "examples": [
    {
      "id": "overview-ex0",
      "language": "checklist {id=\"supabaselist\"}",
      "code": "- [ ] [Create or select a Supabase project](#1-create-or-select-a-supabase-project)\n- [ ] [Configure direct network access](#2-configure-direct-network-access)\n- [ ] [Create a dedicated RDI role](#3-create-a-dedicated-rdi-role)\n- [ ] [Grant access to source tables](#4-grant-access-to-source-tables)\n- [ ] [Configure TLS](#5-configure-tls)\n- [ ] [Configure RDI](#6-configure-rdi)\n- [ ] [Monitor replication slots](#7-monitor-replication-slots)",
      "section_id": "overview"
    },
    {
      "id": "1-create-or-select-a-supabase-project-ex0",
      "language": "sql",
      "code": "SELECT version();",
      "section_id": "1-create-or-select-a-supabase-project"
    },
    {
      "id": "2-configure-direct-network-access-ex0",
      "language": "text",
      "code": "db.<project-ref>.supabase.co",
      "section_id": "2-configure-direct-network-access"
    },
    {
      "id": "3-create-a-dedicated-rdi-role-ex0",
      "language": "sql",
      "code": "CREATE ROLE rdi_replication\n  WITH LOGIN REPLICATION PASSWORD '<strong-password>';",
      "section_id": "3-create-a-dedicated-rdi-role"
    },
    {
      "id": "4-grant-access-to-source-tables-ex0",
      "language": "sql",
      "code": "GRANT CONNECT ON DATABASE postgres TO rdi_replication;\n\nGRANT USAGE ON SCHEMA public TO rdi_replication;\nGRANT SELECT ON ALL TABLES IN SCHEMA public TO rdi_replication;\n\nALTER DEFAULT PRIVILEGES IN SCHEMA public\n  GRANT SELECT ON TABLES TO rdi_replication;",
      "section_id": "4-grant-access-to-source-tables"
    },
    {
      "id": "4-grant-access-to-source-tables-ex1",
      "language": "sql",
      "code": "ALTER ROLE rdi_replication BYPASSRLS;",
      "section_id": "4-grant-access-to-source-tables"
    },
    {
      "id": "create-a-publication-ex0",
      "language": "sql",
      "code": "CREATE PUBLICATION rdi_publication\n  FOR TABLE public.customers, public.orders;",
      "section_id": "create-a-publication"
    },
    {
      "id": "5-configure-tls-ex0",
      "language": "bash",
      "code": "redis-di set-secret SOURCE_DB_USERNAME rdi_replication\nredis-di set-secret SOURCE_DB_PASSWORD '<strong-password>'\nredis-di set-secret SOURCE_DB_CACERT /path/to/prod-ca-2021.crt",
      "section_id": "5-configure-tls"
    },
    {
      "id": "6-configure-rdi-ex0",
      "language": "yaml",
      "code": "sources:\n  supabase:\n    type: cdc\n    connection:\n      type: postgresql\n      host: db.<project-ref>.supabase.co\n      port: 5432\n      database: postgres\n      user: ${SOURCE_DB_USERNAME}\n      password: ${SOURCE_DB_PASSWORD}\n    schemas:\n      - public\n    tables:\n      public.customers: {}\n      public.orders: {}\n    advanced:\n      source:\n        plugin.name: pgoutput\n        publication.name: rdi_publication\n        publication.autocreate.mode: disabled\n        slot.name: rdi_supabase",
      "section_id": "6-configure-rdi"
    },
    {
      "id": "7-monitor-replication-slots-ex0",
      "language": "sql",
      "code": "SELECT\n  slot_name,\n  active,\n  restart_lsn,\n  confirmed_flush_lsn\nFROM pg_replication_slots;",
      "section_id": "7-monitor-replication-slots"
    }
  ]
}
