How to Upgrade Hobby Dev to Hobby Basic in Heroku PostgreSQL

Heroku recently announced that they are going to discontinue the free tiers for Heroku Dynos, Heroku Postgres, and Heroku Redis.

Naturally, I had many Heroku PostgreSQL databases that I needed to upgrade from the hobby-dev plan to the hobby-basic plan.

View the differences between Hobby Dev and Hobby Basic plans in the Heroku Postgres: Plans & Pricing page.

Unfortunately, there is no single button to click that will upgrade our Hobby Dev plan to a Basic plan.

In order to run this upgrade process, we’ll need to create a new database under the Hobby Basic plan, enter maintenance mode, copy all the data over, exit maintenance mode, and destroy the original database.

When upgrading to a higher tier (e.g. Standard, Premium, Private, Shield), we’ll want to use followers for our database. In that case, we can follow the Heroku documentation to upgrade with pg:copy. However, in the hobby tier, we can ignore those steps.

1. Install the Heroku CLI

The first step, of course, is to install the Heroku CLI.

2. Log into Heroku

We’ll want to authenticate ourselves by logging into our Heroku account.

heroku login

We can follow the prompt to log into our Heroku account.

3. List Heroku applications

Let’s list our Heroku applications to confirm the app we’ll be modifying.

heroku apps
=== Apps

=== Collaborated Apps

Let’s say app-1 contains a Heroku Postgres add-on in the free Hobby Dev plan.

Goal: we want to upgrade this PostgreSQL database in app-1 from Hobby Dev to Hobby Basic.

4. Create a new Hobby Basic database

Next, we’ll create a new PostgreSQL database for this app under the hobby-basic plan.

heroku addons:create heroku-postgresql:hobby-basic --app app-1

After running this command, the database will be available but empty. We will transfer data over in a bit.

5. Enter maintenance mode

Next, we’ll enter maintenance mode on this app to prevent database writes during this upgrade process.

heroku maintenance:on --app app-1

Our application will not receive requests once we enable maintenance mode.

6. Get database indicators (colors)

Next, we’ll want to retrieve the database indicator for our Hobby Basic database.

heroku pg:info --app app-1
Plan:                  Hobby-dev
Status:                Available

Plan:                  Hobby-basic
Status:                Available

Our hobby-dev database should be labeled with DATABASE_URL, which is the primary database used by our application.

Our hobby-basic database will have a URL with a different color (in my case, HEROKU_POSTGRESQL_GREEN_URL).

7. Copy data from Hobby Dev to Hobby Basic database

We’ll use pg:copy to copy data from the source to the destination database.

  • From: DATABASE_URL (hobby-dev source)
  • To: HEROKU_POSTGRESQL_GREEN (hobby-basic destination)
heroku pg:copy DATABASE_URL HEROKU_POSTGRESQL_GREEN --app app-1 

This pg:copy method will require roughly 3 minutes of downtime per GB transferred. We can estimate the downtime by performing a dry run (e.g. running pg:copy outside of maintenance mode and without pg:promote).

8. Promote the new database

Once the new database is populated with our data, we can set it as the active database for our application.

heroku pg:promote HEROKU_POSTGRESQL_GREEN --app app-1

Note that our app is still not receiving requests at this point.

9. Exit maintenance mode

To start receiving requests with our new database, let’s exit maintenance mode.

heroku maintenance:off --app app-1

10. Confirm changes

We can confirm that our new Hobby Basic database is our active database (i.e. it’s labeled DATABASE_URL).

heroku pg:info --app app-1
Plan:                  Hobby-basic
Status:                Available

Plan:                  Hobby-dev
Status:                Available

11. Destroy Hobby Dev database

Finally, we can destroy our old Hobby Dev database.

In my case, it’s labeled HEROKU_POSTGRESQL_YELLOW_URL in the pg:info above.

heroku addons:destroy HEROKU_POSTGRESQL_YELLOW --app app-1