Creating and Managing Heroku Postgres Follower Databases
Last updated 19 October 2016
Table of Contents
You can also use
heroku pg:psql with followers to safely run ad-hoc queries against your production data.
Database replication serves many purposes including increasing read throughput with a leader-follower configuration, additional availability with a hot standby, serving as a reporting database, and seamless migrations and upgrades. Though these strategies all serve different purposes they are all based on the ability to create and manage copies of a lead database. On Heroku Postgres, this functionality is exposed as the follow feature.
Followers are only supported on Standard, Premium, and Enterprise tier database plans. Follow these steps to upgrade from a Hobby tier (dev or basic) plan to a production plan.
Followers, like all Heroku Postgres databases, are charged on a pro-rated basis based on the plan of the follower.
A database follower is a read-only copy of the leader database that stays up-to-date with the leader database data. As writes and other data modifications are committed in the leader database, the changes are streamed, in real-time, to the follower databases.
Create a follower
A follower can be created for any Standard, Premium, or Enterprise tier database that is itself not a follower (that is, followers cannot be chained). Followers cannot be created for a period on newly forked databases (this applies to both explicit forks and forks created through unfollow). The exact timeframe varies depending on the size of the database to be followed, and is typically between a few minutes and a few hours.
The follower must be able to accommodate the current data volume of the leader database. If an attempt is made to create a follower that cannot accommodate the data volume, the follower will not be created and an error message will indicate the minimum plan needed.
When a database is ready to support followers, that information will be shown in
$ heroku pg:info === HEROKU_POSTGRESQL_PURPLE_URL (DATABASE_URL) ... Fork/Follow: Available ...
The lag between a leader and follower databases varies greatly depending on the amount and frequency of data updates. It is possible for long running queries on the follower to increase your lag time, though once those queries are done your follower should catch up. Under normal usage, it is common for your follower to be within a few seconds or less of your leader.
To create a follower database you must first know the add-on name of the leader database. Use
heroku pg:info to find its
$ heroku pg:info === HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL) Plan: Standard 0 Status: available ...
If more than one database is listed, the one currently serving as the leader will most often be the one assigned to the
DATABASE_URL (listed after the database name).
Create a follower database by provisioning a new heroku-postgresql Standard, Production or Enterprise tier add-on database and specify the leader database to follow with the
--follow flag. The flag can take either the config var name of the database on the same app, an argument of the form
appname::HEROKU_POSTGRES_COLOR_URL, or the full URL of any Heroku Postgres database.
Followers do not have to be the same database plan as their leader. Production tier database plans can be followed by, and can follow, all other production plans. It is recommended that unless you’re downgrading plans, a follower be created using the same or higher plan than the leader database.
$ heroku addons:create heroku-postgresql:standard-2 --follow HEROKU_POSTGRESQL_CHARCOAL_URL Adding heroku-postgresql:standard-2 to sushi... done, v71 ($200/mo) Attached as HEROKU_POSTGRESQL_WHITE Follower will become available for read-only queries when up-to-date Use `heroku pg:wait` to track status
Preparing a follower can take anywhere from several minutes to several hours, depending on the size of your dataset. The
heroku pg:wait command outputs the provisioning status of any new databases.
$ heroku pg:wait Waiting for database HEROKU_POSTGRESQL_WHITE_URL... available
Create a follower on a different app
Followers do not need to be tied to the same application. With sharable add-ons, the databases can be on two separate applications. The steps are the same as those outlined for creating a follower on the same application with a few slight differences.
heroku pg:info to find the resource name of the database that you want to follow:
$ heroku pg:info -a sushi === HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL) Plan: Standard 0 Status: available Add-on: looking-simply-2449 ...
Once the resource name has been found, type the add-ons command to create the follower on the app that you want it attached to. For example, if a second application is called
other-app and I want to have a follower attached to it using the main database from
$ heroku addons:create heroku-postgresql:standard-0 --follow looking-simply-2449 -a other-app
heroku pg:unfollow command stops the follower from receiving updates from its leader database and transforms it into a full read/write database containing all of the data received up to that point. This creates a database fork.
$ heroku pg:unfollow HEROKU_POSTGRESQL_WHITE_URL ! HEROKU_POSTGRESQL_WHITE_URL will become writable and no longer ! follow HEROKU_POSTGRESQL_CHARCOAL. This cannot be undone. ! WARNING: Potentially Destructive Action ! This command will affect the app: sushi ! To proceed, type "sushi" or re-run this command with --confirm sushi > sushi Unfollowing... done
Unfollowing a database is not the same as de-provisioning it. You will still be charged for the database. To completely de-provision a database use the
heroku addons:destroy HEROKU_POSTGRESQL_WHITE command.
Database upgrades and migrations with changeovers
In addition to providing data redundancy, followers can also be used to change database plans with minimal downtime. To upgrade or migrate your database with a follower, see this guide on upgrading Heroku Postgres.
Because followers are asynchronously updated, they may be behind their leader by some number of commits. You can view the number of commits your follower is behind by running
heroku pg:info. If your follower is increasing in the number of commits it is behind it may be due to long running transactions on your database. Using the pg-extras plugin you can run
heroku pg:ps to get currently running transactions, then if any have been running for longer than expected you may cancel those with:
$ heroku pg:kill PROCESSID
High availability with followers
Heroku Postgres premium plans have the HA feature with automated failover. Read more about how it works.
Having a follower provisioned, even if not being actively used as a read slave, ensures that you always have a hot standby available for immediate promotion in situations where the primary database becomes corrupted or unavailable. As a general practice, applications desiring high-availability should provision a hot standby follower.
Follower databases are guaranteed to be provisioned on geographically separate infrastructure than the primary database.
Heroku does not automatically promote a follower database when the primary database is corrupt or inaccessible. If this functionality is required, use a premium or enterprise tier plan that does offer HA. Performing a database failover is the same manual process as a database migration starting with the prevent data updates step.
Distributing app reads to followers
Heroku allows you to easily horizontally scale your app by adding additional dynos to meet capacity. Similarly, as detailed above, Heroku Postgres allows you to horizontally scale your database by adding read-only followers to the lead database. While these followers are great for analytical purposes, you can also use them via your application for handling read-only queries to your data. This type of architecture can be used to improve app performance as well as work around Heroku Postgres connection limits.
Redirecting your app’s read operations to one or more followers will require changes at the code level of your app. Since each app on Heroku is different, it’s not possible to make a detailed recommendation as to how to proceed. If your app is built using a framework, it’s likely the framework will have support for using multiple databases. In other cases, there will be third party libraries available to help with the handling of multiple databases. In some cases, especially as your app gets more complex, writing custom code will be necessary.