All Products
Search
Document Center

AnalyticDB:How do I migrate a Supabase project

Last Updated:Jan 06, 2026

This topic describes how to use the supabase-cli migration tool to migrate a complete Supabase project to AnalyticDB for PostgreSQL Supabase (AnalyticDB Supabase). The migration includes the database, storage objects, and Edge Functions.

Scenarios

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 content

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

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

  • PostgreSQL extensions: Automatically installs the required plug-ins in the destination project.

  • Storage objects: Includes buckets and the files they contain.

  • Edge Functions: Includes function code and its related configuration.

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

Migration command syntax

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

./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)
    • Self-hosted Supabase project or AnalyticDB Supabase

      --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) and must be percent-encoded
  • Destination environment configuration

    --target-api-url string             # Destination API URL (required)
    --target-anon-key string            # Destination project anonymous key (required) 
    --target-service-role-key string    # Destination project service role key (required)
    --target-database-url string        # Destination database URL (required) and must be percent-encoded

Optional parameters

  • Migration content

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

    --use-local-exec                   # Uses a local executor and does not rely on a Docker container. Tools such as pg_dump must be installed locally.
    --concurrency int                  # Number of concurrent operations (default: 2)
    --dry-run                          # Preview mode. Does not perform the actual migration.
    --resume-from string               # Resumes from a specified step (database|storage|functions)
  • Security options

    Important

    When you use the --allow-truncate parameter, ensure that the source and destination configurations are correct to prevent accidentally clearing data from the source database.

    --allow-truncate                  # Allows clearing table data (default: false)
    --preserve-extra-tables           # Preserves extra tables in the destination database (default: true)

Notes

  • Before you migrate a production environment, fully test the migration flow in a staging environment.

  • Maintain stable network connectivity during the migration.

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

  • Migrate production environments during off-peak hours.

Prerequisites

  • Ensure that the following network connections are stable. For information about specific operations in AnalyticDB Supabase, 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 destination environment.

    • The destination database allows external connections.

  • Docker is installed and running.

Migration steps

Step 1: Obtain project information and configure environment variables

  1. Obtain the source configuration information.

    For Supabase Cloud, obtain the following information from the project 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 URL https://supabase.com/dashboard/project/qeqfhfoebrtkbmwd****, the Project Ref is at the end of the URL (qeqfhfoebrtkbmwd****).

    • Anon Key: The anonymous key, which starts with eyJ.

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

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

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

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

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

    • Database URL: The PostgreSQL connection string. The destination database user must have permissions to create tables, plug-ins, and other objects.

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

    • Migrating 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
    • Migrating 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 migration tool and log on

  1. Download the supabase-cli tool that corresponds to your operating system and architecture. When you run the commands, replace supabase-cli with the name of the downloaded command-line interface (CLI) tool.

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

    ./supabase-cli login

Step 3: (Optional) Preview the migration

Note

If you have not configured environment variables and your database password contains special characters, you must escape the special characters.

  • Migrating 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
  • Migrating 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 Supabase project

Note

If you have not configured environment variables and your database password contains special characters, you must escape the special characters.

Migrate the complete project

  • Migrating 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"
  • Migrating 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" \
      --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 only the database schema and data

You can use the migrate-database subcommand to migrate only the database schema and data.

The following extra 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:

  • Migrating 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"
  • Migrating 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" \
      --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 only storage buckets and objects

You can use the migrate-storage subcommand to migrate only storage buckets and objects.

  • Migrating 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"
  • Migrating 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" \
      --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 only Edge Functions

You can use the migrate-functions subcommand or the functions-cli tool to migrate only Edge Functions.

  • Migrating 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"
  • Migrating 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" \
      --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

How do I resolve the "connections refused" error when connecting to the source database?

You can use 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

How do I resolve the "permission denied for schema auth" error?

  • Use the Service role key instead of the Anon key.

  • Check that the key has sufficient permissions. For information about permission requirements, see Prerequisites.

  • Confirm that the destination database user has administrator permissions.

How do I resolve the "plugin xxx is not available in the target database" error?

You can install the missing plugin in the destination database or remove the unnecessary plugin from the source database.

How do I resolve the sequence conflict error "relation "test_id_seq" already exists"?

You can use the following command:

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

How do I handle special characters in a database connection string?

You can configure the project information as an environment variable. If you do not configure an environment variable, you must escape the special characters as follows:

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