All Products
Search
Document Center

AnalyticDB:Migrate a Supabase project

Last Updated:Apr 08, 2026

This guide explains how to use thesupabase-cli migration tool to migrate a complete Supabase project, including its database, storage objects, and Edge Functions, to AnalyticDB Supabase. This service is powered by AnalyticDB for PostgreSQL.

Use cases

Migration paths

  • Migrate from Supabase Cloud to AnalyticDB Supabase.

  • Migrate from a self-hosted Supabase project to AnalyticDB Supabase.

  • Migrate between AnalyticDB Supabase projects.

Migration scope

  • Database schema: Includes table structures, functions, and triggers.

  • Database data: Includes user data, auth data, and other system data.

  • PostgreSQL extensions: Installs the required plugins in the target project automatically.

  • Storage objects: Includes buckets and the files within them.

  • Edge Functions: Includes function code and related configurations.

  • Roles and permissions: Includes database user and permission settings.

Command syntax

Select the migration tool for your platform and run the following command.

./supabase-cli migrate-project [flags]

Required parameters

  • Source environment configuration

    • Supabase Cloud source configuration

      --source-project-ref string         # Source project reference ID (Required)
      --source-anon-key string            # Source project anonymous key (Required)
      --source-service-role-key string    # Source project service role key (Required)
    • A self-hosted Supabase project or an AnalyticDB Supabase instance

      --source-api-url string             # Source API URL (Required)
      --source-anon-key string            # Source project anonymous key (Required)
      --source-service-role-key string    # Source project service role key (Required)
      --source-database-url string        # Source database URL (Required). Must be percent-encoded.
  • Target environment configuration

    --target-api-url string             # Target API URL (Required)
    --target-anon-key string            # Target project anonymous key (Required) 
    --target-service-role-key string    # Target project service role key (Required)
    --target-database-url string        # Target database URL (Required). Must be percent-encoded.

Optional parameters

  • Supabase Cloud source configuration

    --source-database-url string        # Source database URL (Optional). Must be percent-encoded.
  • Migration content

    --include-data                     # Include database data (default: true)
    --include-storage                  # Include storage objects (default: true)
    --include-functions                # Include Edge Functions (default: true)
    --include-system-data              # Include system module data (default: true)
  • Execution options

    --use-local-exec                   # Use a local executor instead of a Docker container. Requires local installation of tools like pg_dump.
    --concurrency int                  # Number of concurrent operations (default: 2)
    --dry-run                          # Runs in preview mode without performing the migration.
    --resume-from string               # Resume from a specified step (database|storage|functions)
  • Security options

    Important

    When using the--allow-truncate parameter, ensure that the source and target configurations are correct to prevent accidental data deletion from the source database.

    --allow-truncate                  # Allow clearing table data (default: false)
    --preserve-extra-tables           # Preserve extra tables in the target database (default: true)

Usage notes

  • Before migrating a production environment, thoroughly test the migration process in a staging environment.

  • Maintain a stable network connection during the migration.

  • Migrating a large database can take a long time. Plan your migration window accordingly.

  • We recommend performing production environment migrations during off-peak hours.

Prerequisites

  • Ensure the following network connections are stable. For AnalyticDB Supabase-specific operations, see Modify a Whitelist.

    • You can access the API and database of the source Supabase project.

    • You can access the API and database of the target environment.

    • The target database allows external connections.

  • Docker is installed and running.

Procedure

Step 1: Get project information and set environment variables

  1. Obtain the source configuration information.

    For Supabase Cloud, get the following information from your project's settings page.

    • Project Ref: A 20-character project ID.

      • Go to the Supabase console.

      • Click the source project and view the URL. For example, in the URLhttps://supabase.com/dashboard/project/qeqfhfoebrtkbmwd****, the Project Ref is at the end (qeqfhfoebrtkbmwd****).

    • Anon Key: The anonymous key, which starts witheyJ.

    • Service Role Key: The service role key, which starts witheyJ. This key must have permission to read all data.

    • Database URL (Optional): The PostgreSQL connection string.

      On the source project page, click connect, go to the Connection String tab, and select Transaction pooler as the Method.

      image

  2. Obtain the target AnalyticDB Supabase configuration information. For more details, see Obtain API Keys.

    • API URL: The full API address, such ashttps://your-domain.supabase.opentrust.net.

    • Anon Key: The anonymous key for the target environment.

    • Service Role Key: The service role key for the target environment. This key must have full administrative permissions.

    • Database URL: The PostgreSQL connection string. The target database user must have permissions to create tables, plugins, and other objects.

  3. (Optional) To avoid exposing sensitive information on the command line, configure project information as environment variables.

    • Migrate from Supabase Cloud to AnalyticDB Supabase

      # Create a configuration file
      cat > migration.env << 'EOF'
      SOURCE_PROJECT_REF="your-project-ref"
      SOURCE_ANON_KEY="eyJ..."
      SOURCE_SERVICE_ROLE_KEY="eyJ..."
      TARGET_API_URL="https://your-domain.supabase.opentrust.net"
      TARGET_ANON_KEY="eyJ..."
      TARGET_SERVICE_ROLE_KEY="eyJ..."
      TARGET_DATABASE_URL="postgres://postgres:password@{your-project-id}.supabase.opentrust.net:5432/postgres"
      EOF
      
      # Load the environment variables
      source migration.env
    • Migrate from a self-hosted Supabase or AnalyticDB Supabase to AnalyticDB Supabase

      # Create a configuration file
      cat > migration.env << 'EOF'
      SOURCE_API_URL="http://localhost:54321"
      SOURCE_ANON_KEY="eyJ..."
      SOURCE_SERVICE_ROLE_KEY="eyJ..."
      SOURCE_DATABASE_URL="postgres://postgres:password@{your-project-id}.supabase.opentrust.net:5432/postgres"
      TARGET_API_URL="https://your-domain.supabase.opentrust.net"
      TARGET_ANON_KEY="eyJ..."
      TARGET_SERVICE_ROLE_KEY="eyJ..."
      TARGET_DATABASE_URL="postgres://postgres:password@{your-project-id}.supabase.opentrust.net:5432/postgres"
      EOF
      
      # Load the environment variables
      source migration.env

Step 2: Download the tool and log in

  1. Download the supabase-cli tool for your operating system and architecture. In subsequent commands, replacesupabase-cli with the name of the downloaded CLI tool.

  2. Run the following command and follow the prompts to complete the login.

    ./supabase-cli login

Step 3: (Optional) Preview migration

Important
  • If you are not using environment variables and your database password contains special characters, you must escape them.

  • If the Supabase Cloud database is inaccessible and the error "failed to connect to host=db.xxxx.supabase.co user=postgres database=postgres" is returned, specify the--source-database-url parameter as the Transaction pooler address. For details on how to obtain this address, see Step 1: Get project information and set environment variables.

  • Migrate from Supabase Cloud to AnalyticDB Supabase

    ./supabase-cli migrate-project \
      --source-project-ref "$SOURCE_PROJECT_REF" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL" \
      --dry-run
  • Migrate from a self-hosted Supabase or AnalyticDB Supabase to AnalyticDB Supabase

    ./supabase-cli migrate-project \
      --source-hosted \
      --source-api-url "$SOURCE_API_URL" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --source-database-url "$SOURCE_DATABASE_URL" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL" \
      --dry-run

Step 4: Migrate the project

Important
  • If you are not using environment variables and your database password contains special characters, you must escape them.

  • If the Supabase Cloud database is inaccessible and the error "failed to connect to host=db.xxxx.supabase.co user=postgres database=postgres" is returned, specify the--source-database-url parameter as the Transaction pooler address. For details on how to obtain this address, see Step 1: Get project information and set environment variables.

Complete project

  • Migrate from Supabase Cloud to AnalyticDB Supabase

    ./supabase-cli migrate-project \  
      --source-project-ref "$SOURCE_PROJECT_REF" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"
  • Migrate from a self-hosted Supabase or AnalyticDB Supabase to AnalyticDB Supabase

    ./supabase-cli migrate-project \
      --source-hosted \
      --source-api-url "$SOURCE_API_URL" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --source-database-url "$SOURCE_DATABASE_URL" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"

Database schema and data

Use themigrate-database subcommand to migrate only the database schema and data.

The following additional parameters are supported:

  • --include-data: Specifies whether to include data.

  • --include-system-data: Specifies whether to include system data.

  • --allow-truncate: Specifies whether to allow clearing table data.

  • --preserve-extra-tables: Specifies whether to preserve extra tables.

The following examples show how to use this subcommand:

  • Migrate from Supabase Cloud to AnalyticDB Supabase

    ./supabase-cli migrate-project migrate-database \  
      --source-project-ref "$SOURCE_PROJECT_REF" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"
  • Migrate from a self-hosted Supabase or AnalyticDB Supabase to AnalyticDB Supabase

    ./supabase-cli migrate-project migrate-database \
      --source-hosted \
      --source-api-url "$SOURCE_API_URL" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --source-database-url "$SOURCE_DATABASE_URL" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"

Storage buckets and objects

Use themigrate-storage subcommand to migrate only storage buckets and objects.

  • Migrate from Supabase Cloud to AnalyticDB Supabase

    ./supabase-cli migrate-project migrate-storage \  
      --source-project-ref "$SOURCE_PROJECT_REF" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"
  • Migrate from a self-hosted Supabase or AnalyticDB Supabase to AnalyticDB Supabase

    ./supabase-cli migrate-project migrate-storage \
      --source-hosted \
      --source-api-url "$SOURCE_API_URL" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --source-database-url "$SOURCE_DATABASE_URL" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"

Edge Functions

Use themigrate-functions subcommand or the functions-cli tool to migrate only Edge Functions.

  • Migrate from Supabase Cloud to AnalyticDB Supabase

    ./supabase-cli migrate-project migrate-functions \  
      --source-project-ref "$SOURCE_PROJECT_REF" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"
  • Migrate from a self-hosted Supabase or AnalyticDB Supabase to AnalyticDB Supabase

    ./supabase-cli migrate-project migrate-functions \
      --source-hosted \
      --source-api-url "$SOURCE_API_URL" \
      --source-anon-key "$SOURCE_ANON_KEY" \
      --source-service-role-key "$SOURCE_SERVICE_ROLE_KEY" \
      --source-database-url "$SOURCE_DATABASE_URL" \
      --target-api-url "$TARGET_API_URL" \
      --target-anon-key "$TARGET_ANON_KEY" \
      --target-service-role-key "$TARGET_SERVICE_ROLE_KEY" \
      --target-database-url "$TARGET_DATABASE_URL"

FAQ

Resolve "connections refused" error

Run the following command to check network connectivity.

# Check network connectivity
ping db.your-project-ref.supabase.co

# Check the database URL format
# Correct format: postgres://postgres:password@host:port/database

Resolve "permission denied" error

  • Ensure that you are using the service role key, not the anonymous key.

  • Check whether the key has sufficient permissions. For permission requirements, see Prerequisites.

  • Confirm that the target database user has administrator permissions.

Resolve "plugin not available" error

Install the missing plugin in the target database, or remove the unnecessary plugin from the source database.

Resolve "relation already exists" error

Use the following command:

# Use a safer table cleanup policy
supabase migrate-project ... --preserve-extra-tables=true --allow-truncate=true

Handle special characters in connection strings

Configuring project information as environment variables is recommended. Otherwise, you must escape any special characters in your password as follows:

! : %21
@ : %40
# : %23
$ : %24
% : %25
^ : %5e
& : %26
* : %2a
( : %28
) : %29
_ : %5f
+ : %2b
= : %3d