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, auth data, and other system data.
PostgreSQL extensions: Automatically installs the required extensions in the destination project.
Storage: Buckets and the files they contain.
Edge Functions: Function code and related configurations.
Roles and permissions: Database user roles and permissions.
Migration command syntax
Download the migration tool for your platform and run the following command to migrate.
./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
Supabase Cloud source configuration
--source-database-url string # Source database URL (optional) and must be percent-encodedMigration 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
ImportantWhen you use the
--allow-truncateparameter, ensure that the source and destination configurations are correct to prevent accidental data deletion 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 available. For more 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
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 the last part 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.Database URL (Optional): The PostgreSQL connection string.
Click Connect at the top of the source project page. On the Connection String tab, set Method to Transaction pooler.

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 permission.
Database URL: The PostgreSQL connection string. The destination database user must have permissions to create tables, extensions, and other objects.
(Optional) Configure the project information as environment variables to avoid exposing sensitive information on the command line.
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.envMigrating 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
Download the supabase-cli tool for your operating system and architecture. When you run the commands, replace
supabase-cliwith the name of the downloaded CLI tool.Run the following command and follow the prompts to log on.
./supabase-cli login
Step 3: (Optional) Preview the migration
If you have not configured environment variables and your database password contains special characters, you must escape the special characters.
If the Supabase Cloud database is inaccessible and the error "failed to connect to host=db.xxxx.supabase.co user=postgres database=postgres" is reported, specify the
--source-database-urlparameter as the Transaction pooler address. For more information about how to obtain the address, see Step 1: Obtain project information and configure environment variables.
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-runMigrating 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
If you have not configured environment variables and your database password contains special characters, you must escape the special characters.
If the Supabase Cloud database is inaccessible and the error "failed to connect to host=db.xxxx.supabase.co user=postgres database=postgres" is reported, specify the
--source-database-urlparameter as the Transaction pooler address. For more information about how to obtain the address, see Step 1: Obtain project information and configure environment variables.
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" \ --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"
Migrate only the database schema and data
Use the migrate-database subcommand to migrate only the database schema and data.
Supported additional parameters:
--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.
Example:
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" \ --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"
Migrate only storage buckets and objects
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" \ --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"
Migrate only Edge Functions
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" \ --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
How do I resolve the "connections refused" error when connecting to the source database?
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/databaseHow do I resolve the "permission denied for schema auth" error?
Ensure that you are using the Service role key, not the Anon key.
Check that the key has sufficient permissions. For more information about permission requirements, see Prerequisites.
Confirm that the destination database user has administrative permission.
How do I resolve the "plugin xxx is not available in the target database" error?
Install the missing extension, or remove the unnecessary extension from the source database.
How do I resolve the sequence conflict error "relation "test_id_seq" already exists"?
Use the following command:
# Use a safer table cleanup policy
supabase migrate-project ... --preserve-extra-tables=true --allow-truncate=trueHow do I handle special characters in a database connection string?
Configure the project information as an environment variable. If you do not configure an environment variable, escape the special characters as follows:
! : %21
@ : %40
# : %23
$ : %24
% : %25
^ : %5e
& : %26
* : %2a
( : %28
) : %29
_ : %5f
+ : %2b
= : %3d