Migrating from UpCloud Managed PostgreSQL to Heroku Postgres
Last updated March 28, 2025
Table of Contents
In this guide, we walk you through the process of migrating your Postgres database from UpCloud-managed PostgreSQL to Heroku Postgres. This guide uses UpCloud Object Storage to store the database dump file. Before starting the migration, make sure you completed the steps from Preparing Your Migration to Heroku Postgres.
Get Your Database Size
In most cases, the dump and restore strategy for migration is suitable if your database size is less than 100 GB. With a managed database from UpCloud, you can estimate your database size either through the web UI or through querying the database with the psql
client.
In your UpCloud account, go to Databases
and click on your database. Navigate to the Statistics
tab to see Disk space usage
. Hover your mouse over the chart to see the storage usage.
In the example, the storage is 1.78% of the total 25 GB of storage for this instance, or approximately 440 MB. However, this number includes all storage for the system running on your managed instance, including system files, installations, and more. So, the actual database size is only a fraction of this number.
For a more accurate size reading, connect to your database instance and use the list databases \l+
command. You can find the Postgres credentials for your database in the Public connection
section on the database information page.
Show and copy the connection string. The connection string for using the psql
client uses the format:
postgres://DB_USERNAME:DB_PASSWORD@DB_HOST:DB_PORT/DB_NAME
Our example database is called Adventureworks
, so we connect our database to the psql
client with:
$ psql postgres://upadmin:mydatabasepassword@public-demo-schcpsmhczcm.db.upclouddatabases.com:11569/Adventureworks
After connecting, you can show the database size with the list databases \l+
command:
$ psql=> \l+
List of databases
Name | Owner | Encoding | Collate | Size |
----------------+-----------+----------+-------------+--------+
Adventureworks | democoder | UTF8 | en_US.UTF-8 | 112 MB |
The Size
column shows our database size is 112 MB.
See Choosing the Right Heroku Postgres Plan for which Heroku Postgres plan fits your database size.
Prepare the Database Dump
Before starting, either set your system to read-only mode, or bring all your dependent services offline and notify end users of the current maintenance status.
If your database is attached to a Heroku app, put your app in maintenance mode.
Back Up Your Database
Before performing the migration, make sure you have a recent backup of your database on UpCloud. UpCloud takes periodic snapshot backups of your managed Postgres database. Navigate to the Backups
page for your database to check the recency of your latest backup.
Dump the Database to a Local File
Using pg_dump
, dump your UpCloud database to a local file:
$ pg_dump postgres://DB_USERNAME:DB_PASSWORD@DB_HOST:DB_PORT/DB_NAME \
-Fc -b -v \
-f /tmp/data-for-migration.sql
The time it takes to run this command varies depending on the size of your database. You can keep an eye on the file size of /tmp/data-for-migration.sql
to verify that the long process is running.
Upload the File to UpCloud Object Storage
Heroku can restore a Postgres database from a file that’s accessible via a URL. For this migration, you can upload your data backup file to Object Storage from UpCloud, which is S3-compatible.
First, create a bucket. In our example, we named our bucket postgres-for-migration
.
After creating your bucket, upload the /tmp/data-for-migration.sql
file from the Dump the Database to a Local File step. The bottom of your Object Storage
page for UpCloud has a section called AWS CLI connection guide
.
This section shows you how to configure your local machine so that you can use the AWS CLI to access your UpCloud object storage just like you would with AWS S3. With your AWS profile set up to access UpCloud, upload your data backup file to your UpCloud object storage bucket.
$ aws s3 cp \
/tmp/data-for-migration.sql \
s3://postgres-for-migration/data-for-migration.sql \
--profile=upcloud
$ aws s3 ls \
s3://postgres-for-migration \
--profile=upcloud
2024-09-29 21:00:00 19289064 data-for-migration.sql
Perform the Restore Migration
Create a Heroku app
Use the Heroku CLI to log into your Heroku account.
$ heroku login
Next, create a Heroku app and provide a name for it, such as postgres-migration-from-upcloud
.
$ heroku apps:create psql-migration-from-upcloud
Creating ⬢ psql-migration-from-upcloud... done
Create the Heroku Postgres Add-on
After creating your Heroku app, add the Heroku Postgres add-on with an appropriate plan. Based on the database information from Get Your Database Size, we use the Essential-1 Postgres plan.
$ heroku addons:create \
--app psql-migration-from-upcloud \
heroku-postgresql:essential-1
Creating heroku-postgresql:essential-1 on ⬢ psql-migration-from-upcloud... ~$0.013/hour (max $9/month)
Database should be available soon
postgresql-rectangular-63793 is being created in the background. The app will restart when complete...
Use heroku addons:info postgresql-rectangular-63793 to check creation progress
Use heroku addons:docs heroku-postgresql to view documentation
Heroku begins provisioning a Postgres database for your Heroku app, providing a unique name. Within a few minutes, you can run the following command with the database name to see the created database.
$ heroku addons:info postgresql-rectangular-63793
=== postgresql-rectangular-63793
Attachments: psql-migration-from-upcloud::DATABASE
Installed at: Sun Sep 29 2024 21:30:00 GMT-0700 (Mountain Standard Time)
Max Price: $9/month
Owning app: psql-migration-from-upcloud
Plan: heroku-postgresql:essential-1
Price: ~$0.013/hour
State: created
Install Necessary Extensions for Heroku Postgres
Before migrating data, install any extensions you had in your UpCloud Postgres instance.
First, to see what extensions are already installed on your Heroku Postgres instance, connect to your Heroku Postgres instance with pg:psql
:
$ heroku pg:psql --app psql-migration-from-upcloud
--> Connecting to postgresql-rectangular-63793
psql (16.4 (Ubuntu 16.4-1.pgdg20.04+1), server 16.2)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
psql=> \dx
List of installed extensions
Name | Version | Schema | Description
--------------------+---------+------------+-------------------------------
pg_stat_statements | 1.10 | public | track planning and executio...
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(2 rows)
Install any extensions you had at UpCloud that aren’t already in Heroku Postgres. For our example, we need the tablefunc
and sslinfo
extensions.
$ psql=> CREATE EXTENSION IF NOT EXISTS tablefunc;
CREATE EXTENSION
psql=> CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION
psql=> \dx
List of installed extensions
Name | Version | Schema | Description
--------------------+---------+------------+-------------------------------
pg_stat_statements | 1.10 | public | track planning and execution…
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
tablefunc | 1.0 | public | functions that manipulate…
uuid-ossp | 1.1 | public | generate universally unique…
(4 rows)
See Extensions, PostGIS, and Full Text Search Dictionaries on Heroku Postgres for supported extensions and how to install them.
Get the Signed URL For the File in UpCloud Object Storage
Next, restore all the data from your pg_dump
backup to your new Heroku Postgres database. For this, you need a URL that points to your backup file. Similar to uploading your file, you’ll use the aws
CLI.
In the operation, s3 presign
takes the S3 URI for the file we want to access. We also set --expires-in
to 600 seconds or 10 minutes to access and use this file for Heroku’s database restoration process.
In our example, the signed URL for our database dump file is:
https://l40iu.upcloudobjects.com/postgresql-for-migration/data-for-migration.sql?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA01A66C4C55E16975%2F20240930%2Feurope-1%2Fs3%2Faws4_request&X-Amz-Date=20240930T045349Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=b70c61e1957311346455c64e0229e8e1415347cf163eb481e7b7f4486ae06984
Restore on Heroku
Now that you have the presigned URL, use the Heroku pg:backups:restore
command to restore your Heroku Postgres database from your UpCloud Object Storage file. The command looks like:
$ heroku pg:backups:restore 'UPCLOUD-PRESIGNED_URL-IN-QUOTES' \
--app psql-migration-from-upcloud \
--confirm psql-migration-from-upcloud
Use Ctrl-C at any time to stop monitoring progress; the backup will continue restoring.
Use heroku pg:backups to check progress.
Stop a running restore with heroku pg:backups:cancel.
Starting restore of [UPCLOUD-PRESIGNED-URL] to postgresql-rectangular-63793... done
Restoring... done
Keep in mind with this command:
- When you paste in your UpCloud Object Storage-signed URL, make sure to contain it within quotes.
- Provide the
--app
argument to tell Heroku which application and corresponding database you want to operate on. - This command is destructive, requiring you to confirm it. If you don’t provide the
--confirm
argument, you’re asked to confirm the action before continuing.
Migrate Any Custom Settings
Just as you saved your UpCloud Postgres configurations to a file called /tmp/settings_postgres.csv
, you can do the same for your Heroku Postgres configuration with the command:
$ heroku pg:psql --app psql-migration-from-upcloud \
-c "\copy (select * from pg_settings) to '/tmp/settings_heroku.csv' with (format csv, header true);"
Compare your Heroku Postgres settings with your UpCloud Postgres settings. Find any configurations from your UpCloud Postgres setup and reapply them to your Heroku Postgres instance.
Testing and Verifying a Successful Migration
We recommend testing to verify that data has migrated over successfully. Testing can include:
- Comparing table counts between the two databases.
- Comparing row counts for every table between the two databases.
- Comparing query results between the two databases.
- Running various acceptance tests on your new database, validating proper behavior and performance.
Connecting Existing Applications and Services
After verifying that the database migration was successful, point your existing applications and services to the new database.
Get Heroku Postgres Credentials
When you create the Heroku Postgres add-on, Heroku automatically configures a new environment variable called DATABASE_URL
, which contains the credentials and connection information for your new database. Run the heroku config:get
command to fetch the variable:
$ heroku config:get DATABASE_URL --app psql-migration-from-upcloud
postgres://u4pjafvp2at0o7:paa9b63e0bd441af5e1b2d829bf0e4601063b4cbb66dceeb4736b2e3db141c85d@cenqjqs4iipva2.cluster-czrs8kj4isg7.us-east-1.rds.amazonaws.com:5432/d32ljn8e55ahm5
You can also find your credentials with the heroku:pg:credentials
command.
The Postgres URI follows this format, so that you can parse the individual pieces:
postgres://DB_USERNAME:DB_PASSWORD@DB_HOST:DB_PORT/DB_NAME
Update Dependent Systems and Test
Update your existing systems to point to Heroku Postgres with this information. Test each system to make sure the connection is successful.
At this point, you can also suspend your UpCloud database. Click the Shut down
button at the top right of your UpCloud database page.
Wrap-up
Now that your applications and services are pointing to Heroku Postgres and running as expected, you can close the maintenance window and restore full availability to your end users.
When you’re confident that the migration is successful and you no longer need your UpCloud database, you can delete it completely.
With your migration complete, you can now enjoy the flexibility and low-cost convenience of Heroku Postgres. See our Heroku Postgres documentation for more information on using your database.