Last updated 12 September 2017
Heroku add-ons are components, services, or pieces of infrastructure that are fully maintained for you, either by a third-party provider or by Heroku. Building on top of Heroku’s core service, add-ons exist so that developers can focus on their own application logic, and not the additional complexity of keeping supporting services or components running at full production capacity.
Add-ons can be used to handle a lot of ancillary components to your application, including data storage, monitoring, analytics, data processing, and more. Browse the available add-ons by category in the Elements Marketplace.
Visit Heroku Elements to see the full list of add-ons available to Heroku developers.
Add-ons are installed onto applications by using the Heroku Dashboard or the CLI. Most add-ons offer multiple plans, with different features, capabilities, and prices. Add-on plans are priced by the month, and prorated to the second.
You can add an add-on to your app via either Dashboard or the CLI. The Elements site has instructions for both, and a CLI example is below.
Once one is added to your app, it is available as one or more config vars (environment variables).
|Addon Service||Default Config Var(s)|
|Example Service||EXAMPLESERVICE_USERNAME, EXAMPLESERVICE_PASSWORD|
You can see these config vars in Dashboard in the “Attachment Details” for the specific installed addon instance.
Also, some add-ons have their own dashboard (for that specific add-on resource), which is accessible from both Dashboard and CLI.
CLI Installation Example
You can install an add-on using the
heroku addons:create SERVICE command,
which will provision the add-on with its provider, give the add-on a global
name and give a default alias to it on your application, and set any config var
the add-on provides using names based on that alias.
This example provisions the Heroku Redis add-on and installs it in your hypothetical app named
$ heroku addons:create heroku-redis --app important-app Creating shining-calmly-4402... done, (free) Adding shining-calmly-4402 to important-app... done Setting REDIS_URL and restarting important-app... done, v3
The CLI output shows that the global name for the newly installed add-on is
shining-calmly-4402, the alias for the add-on on the application is
REDIS (the default for this add-on service), and, consequently, the
config var set is
REDIS_URL. config vars vary for each add-on and they are described in each add-on’s documentation. For example, see the Heroku Redis documentation.
We can see the add-on details at any time with the
heroku addons command:
$ heroku addons --app important-app === Resources for important-app Plan Name Price ---------------------- ------------------- ----- heroku-redis:hobby-dev shining-calmly-4402 free === Attachments for important-app Name Add-on Billing App ----- ------------------- ------------- REDIS shining-calmly-4402 important-app
The resources section lists add-ons that are owned by the application, along
with relevant details about the add-on such as its plan, its global name, and
its cost. The attachments section lists all the add-ons that are attached to
this application (that is, that have an alias to an add-on), regardless of whether this
app owns it or not. This is where we can see that
REDIS is an alias to our
shining-calmly-4402 add-on we just installed. Right now the distinction between an add-on’s resource and its attachment might seem unnecessary, but we’ll look at some important stories in the next section below that show why it’s important.
By installing the add-on, we’ve delegated management of any environment
variable prefixed with the alias
REDIS to that add-on. In the case of
heroku-redis only a
URL variable is used, so
REDIS_URL is set by the
$ heroku config --app important-app REDIS_URL: redis://h:email@example.com:6569
There are a few ways you can more finely control how add-ons are associated with applications.
- By default an addon resource is given a haiku name such as
shining-calmly-4402- but you can custom name an addon.
- Some add-ons can have multiple names within an app
- Some add-ons can be attached to multiple apps
The global name for our add-on,
shining-calmly-4402, isn’t necessarily very
meaningful. Just like apps, you don’t have to choose a name if you don’t want
to, but often it can be crucial as your application grows in complexity.
We can give an add-on a meaningful name when it is initially created by using the
$ heroku addons:create heroku-redis --app important-app --name important-redis Creating important-redis... done, (free) Adding important-redis to important-app... done Setting REDIS_URL and restarting important-app... done, v7
Now, wherever the add-on instance is identified, it will have a recognizable name:
$ heroku addons --app important-app === Resources for important-app Plan Name Price ---------------------- --------------- ----- heroku-redis:hobby-dev important-redis free === Attachments for important-app Name Add-on Billing App ----- --------------- ------------- REDIS important-redis important-app
Sometimes, the name of the alias is important and relevant to the application.
For example, in the Python world, the popular task/job queue
Celery can use any of
several backend storage systems, including Redis. The library looks at the
BROKER_URL by default and uses the URL transport protocol to
decide which backend to use.
Suppose we want to use Redis as the queue backend on our
Because add-on config vars are prefixed with the alias, we can choose
a non-default alias so that Celery easily uses our Redis instance as its
$ heroku addons:create heroku-redis --app important-app --name important-redis --as BROKER Creating important-redis... done, (free) Adding important-redis to important-app... done Setting BROKER_URL and restarting important-app... done, v9
Alias names must always conform to the same naming conventions as config vars.They must begin with a letter and can only contain uppercase alphanumeric characters or underscores.
As shown in the output above, we see that
BROKER_URL is set on our
application instead of the usual default
REDIS_URL. We can see this in the
heroku config output too:
$ heroku config --app important-app BROKER_URL: redis://h:firstname.lastname@example.org:6599
Not all add-ons support choosing your own alias.
Sometimes, it is useful to have multiple aliases with which to refer to an
add-on. As an example, suppose we want to use the same Redis instance from the
previous example as a session store in addition to a task queue broker. We can
achieve this with
heroku addons:attach EXISTING_ADDON which links an add-on
to an app with a new alias:
$ heroku addons:attach important-redis --app important-app --as SESSION_STORE Attaching important-redis as SESSION_STORE to important-app... done Setting SESSION_STORE vars and restarting important-app... done, v10
For convenience, you may also refer to the add-on by one of its
existing aliases. For example, the command above could have been
addons:attach BROKER --as SESSION_STORE.
Once the attachment is created, we can see the extra alias in
and the new config vars added as a result with
$ heroku addons --app important-app === Resources for important-app Plan Name Price ---------------------- --------------- ----- heroku-redis:hobby-dev important-redis free === Attachments for important-app Name Add-on Billing App ------------- --------------- ------------- BROKER important-redis important-app SESSION_STORE important-redis important-app $ heroku config --app important-app BROKER_URL: redis://h:email@example.com:6599 SESSION_STORE_URL: redis://h:firstname.lastname@example.org:6599
Note that there are two attachments listed but both correspond with the single
important-redis add-on. Also note that both config vars have the
Using multiple aliases for an add-on offers many conveniences, but it’s important to note that it might result in using higher usage of the add-on’s available resources. For instance, in the example above, you might be creating more connections to the Redis instance than you otherwise would have if you shared the connection for each usage in your application.
The ability to create multiple aliases can also be used to rename an alias
and its corresponding config vars by creating a second attachment and
then removing the original one with
heroku addons:detach ATTACHMENT_NAME.
Not all add-ons support multiple attachments to the same add-on.
Sharing an add-on between apps
As shown above, the
heroku addons:attach command is used to create extra
aliases for an add-on on an application. We can take advantage of this to create aliases for an add-on on a different application, as
long as they both have the same owner.
Not all add-ons can be shared between applications.
For example, suppose the tasks that we are enqueuing to our broker (from the
earlier examples) need to be processed by a different component in a different
important-tasker. We can share the add-on with the second
application using any alias we like (or the default), but let’s reuse
so that we’ll understand its purpose in the future:
$ heroku addons:attach important-redis --app important-tasker --as BROKER Attaching important-redis as BROKER to important-tasker... done Setting BROKER vars and restarting important-tasker... done, v3
Alias names must be unique on any one application but it’s perfectly fine to use the same alias on two different applications.
For convenience, you may also refer to the add-on by one of its existing
aliases. Since we are involving two applications, we’ll need to be specific
and scope the alias by its application. For example, the command above
could have been
heroku addons:attach important-app::BROKER --as SESSION_STORE --app important-tasker.
Let’s look at the add-ons and config vars on our second application:
$ heroku addons -a important-tasker === Resources for important-tasker There are no add-ons. === Attachments for important-tasker Name Add-on Billing App ------ --------------- ------------- BROKER important-redis important-app $ heroku config -a important-tasker BROKER_URL: redis://h:email@example.com:6599
Notice how there are no add-on resources owned by the
application but that it does have an attachment named
BROKER to the add-on
important-redis, which is billed to the app
note that the
BROKER_URL shares a value with its kin on
the add-on provider needed to change this value for any reason, both of these
applications would automatically be restarted with the new value set.
Installing more than one of the same add-on service onto an app
Most add-ons are designed to be installed just once on any given application, but some add-ons can be installed multiple times.
For example, suppose we wanted to have our task broker and our session store backed by different instances of Redis. We might want to do this for a number of reasons, such as limiting what data is accessible when we share an add-on or because each use case has different semantics offered by different plans or different third-party providers (for example, choosing between durability and processing speed).
We can create a second Redis instance easily enough:
$ heroku addons:create heroku-redis --app important-app Creating sighing-nobly-1891... done, (free) Adding sighing-nobly-1891 to important-app... done Setting REDIS_URL and restarting important-app... done, v11
We can even create a third:
$ heroku addons:create heroku-redis --app important-app Creating cooling-carefully-7273... done, (free) Adding cooling-carefully-7273 to important-app... done Setting HEROKU_REDIS_ROSE_URL and restarting important-app... done, v12
Note how the one installation used the default alias of
REDIS while the
HEROKU_REDIS_ROSE_URL. If you do not provide an alias with
--as, Heroku will choose one for you. More information on how these names
are chosen can be seen in the next section.
Since we want to use a new Redis instance for our session store, let’s replace
SESSION_STORE alias with one pointing to our new add-on:
$ heroku addons:attach sighing-nobly-1891 --as BROKER --app important-app Attaching sighing-nobly-1891 as BROKER to important-app... ! sighing-nobly-1891 will overwrite BROKER_URL on important-app. ! To proceed, type "important-app" or re-run this command with --confirm important-app >
Because we are replacing an existing alias and config var, we need to confirm our intent. When we confirm, the attachment and its environment variables are replaced:
> important-app Attaching sighing-nobly-1891 as BROKER to important-app... done Setting BROKER vars and restarting important-app... done, v14 $ heroku addons --app important-app === Resources for important-app Plan Name Price ---------------------- ---------------------- ----- heroku-redis:hobby-dev cooling-carefully-7273 free heroku-redis:hobby-dev important-redis free heroku-redis:hobby-dev sighing-nobly-1891 free === Attachments for important-app Name Add-on Billing App ----------------- ---------------------- ------------- BROKER sighing-nobly-1891 important-app HEROKU_REDIS_ROSE cooling-carefully-7273 important-app REDIS sighing-nobly-1891 important-app SESSION_STORE important-redis important-app $ heroku config --app important-app BROKER_URL: redis://h:firstname.lastname@example.org:6609 HEROKU_REDIS_ROSE_URL: redis://h:email@example.com:6619 REDIS_URL: redis://h:firstname.lastname@example.org:6609 SESSION_STORE_URL: redis://h:email@example.com:6599
HEROKU_REDIS_ROSE each point to a
different add-on instance and each have unique values set to their
corresponding config vars. Since the add-on aliased as
HEROKU_REDIS_ROSE was just created as an example and the
REDIS alias is
redundant in our scenario, let’s remove them:
$ heroku addons:detach REDIS --app important-app Removing REDIS attachment to sighing-nobly-1891 from important-app... done Unsetting REDIS vars and restarting important-app... done, v15 $ heroku addons:destroy cooling-carefully-7273 ! WARNING: Destructive Action ! This command will affect the app: important-app ! To proceed, type "important-app" or re-run this command with --confirm important-app > important-app Destroying cooling-carefully-7273 on important-app... done, (free) Removing vars for HEROKU_REDIS_ROSE from important-app and restarting... done, v16
Notice that the
addons:detach command removed an attachment alias (
addons:destroy deprovisioned the add-on (
cooling-carefully-7273) as well as any associated attachments (such as
Now everything looks the way we want with two distinct instances, one of which is
BROKER to both of our applications:
$ heroku addons --app important-app === Resources for important-app Plan Name Price ---------------------- ------------------ ----- heroku-redis:hobby-dev important-redis free heroku-redis:hobby-dev sighing-nobly-1891 free === Attachments for important-app Name Add-on Billing App ------------- ------------------ ------------- BROKER sighing-nobly-1891 important-app SESSION_STORE important-redis important-app $ heroku addons --app important-tasker === Resources for important-tasker There are no add-ons. === Attachments for important-tasker Name Add-on Billing App ------ --------------- ------------- BROKER important-redis important-app
Advanced usage examples to play with
Here are some example use cases you can use to experiment with add-ons. These scenarios are based on real instances within Heroku itself.
- Share a secret key between two applications with the Secure Key add-on. Experiment with different installations, each for a different purpose (e.g. a session key and an encryption key).
- Share several applications’ Heroku Postgres databases with a single application acting as a data warehouse. Name each alias based on the app to whose database it points.
- Share a message queue such as CloudAMQP between multiple apps to listen to events from each other.
- Create several
RedisCloud instances and
observe the aliases automatically chosen. Use
heroku addons:attachto replace an alias that already exists so you can change which instance your application uses.
- Replace a RedisCloud instance with a Heroku Redis instance (or vice versa) by installing it with the alias that the existing instance already uses.
- Try to remove the only alias to an add-on and observe the error message.
What an app developer can do with add-ons
- Install any number of add-ons to an application.
- Install multiple instances of the same add-on to the same application, in some cases.
- Share certain add-ons between multiple applications that have the same owner.
- Log in to the add-on dashboard for more actions.
What add-ons can do with your app
An add-on can interact with your Heroku application(s) in a few ways, including:
- Add and update specific config vars to the application(s) using the add-on.
- Write to logs.
- Read logs.
- Listen to deploy events.
- Listen to domain add or remove events.
- View app information.
- View app owner information.
Attachment names / aliases
When installing or attaching add-ons, the attachment must have a name/alias that is unique to that application. This is so that we can distinguish between multiple attachments for the same add-on and so that the config vars do not conflict.
Here are some examples of how config vars are computed:
|Addon service||Default attachment name||Suffix(es)||Default config var|
|Example Service||exampleservice||_username, _password||EXAMPLESERVICE_USERNAME, EXAMPLESERVICE_PASSWORD|
In order to minimise the decisions you must make when installing an add-on, Heroku automatically assigns aliases based on a few simple rules to handle naming conflicts.
In essence, an attachment name is chosen as follows:
The user’s choice, if provided.
If provided but presents a conflict, confirmation to overwrite it is requested.
The default alias, as selected by the add-on provider, if available.
Usually, this is a derivative of the name of the add-on service (e.g. IronCache’s service name is
iron_cacheand its default alias is
IRON_CACHE, while Heroku Postgres’ service name is
heroku-postgresqlbut its chosen default alias is
A generated alias based on the add-on service name and a random color.
For example, when
DATABASEis already taken, a name like
HEROKU_POSTGRESQL_CYANis chosen for Heroku Postgres; and when
REDISCLOUDis already taken, a name like
REDISCLOUD_BLUEis chosen for the add-on RedisCloud.
You may always provide your own alias with the
--as option when running
heroku addons:create or
heroku addons:attach. The name must be unique
within the scope of that application otherwise you may be presented with a
confirmation to overwrite the existing one.
Furthermore, when an identifier for an add-on instance (such as
important-redis) is expected in a command, you may also use any known alias
for that add-on as an identifier. The add-on is resolved by looking at the
current application and the provided alias. If you need to refer to an add-on
by an alias on a different application, you may use the long form version of
Be careful when using the attachment name in destructive commands as it can
be easy to forget you are operating on the add-on as a whole. For instance
heroku addons:destroy SOME_ATTACHMENT actually uninstalls the
add-on (after confirmation) and might be mistaken for
heroku addons:detach SOME_ATTACHMENT
which just removes a single alias.
Config var values can change
A config var provides your application with information on how to access the add-on service. An add-on config var is typically in a URL format, encoding credentials, host and port information, resource names, and even protocol information (such as in the example above).
Because add-ons have access to their config vars within your application, they can change them in some cases, such as in the event of a failure of underlying infrastructure that would necessitate a failover. In such a case, the add-on provider may switch the service over to a different part of their infrastructure and communicate this change by updating the value of the corresponding config var.
When a config var changes, the application is automatically restarted with the resulting release. It is therefore important that applications neither use hard-coded add-on config var values in code or configuration, nor cache config var values during their build, in order to keep interruption of service as minimal as possible. Config vars should always dynamically be read at runtime or during application startup instead.