Add-ons Overview
Last updated October 11, 2024
Table of Contents
Heroku add-ons are components that support your application, such as data storage, monitoring, analytics, data processing, and more. These are fully maintained for you by either a third-party provider or by Heroku. Add-ons exist so that developers can focus on their own application logic, and not the additional complexity of keeping supporting services running at full production capacity.
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 only pay for the time you use them. For example, a Mini Heroku Key-Value Store (KVS) instance costs $3/month. If you create a Mini Heroku Key-Value Store instance and delete it after 15 days, it will cost you roughly $1.50.
Basic Usage
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) |
---|---|
Heroku Postgres | DATABASE_URL |
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 Key-Value Store add-on and installs it in your hypothetical app named example-app
.
$ heroku addons:create heroku-redis --app example-app
Creating shining-calmly-4402... done, ($3/month)
Adding shining-calmly-4402 to example-app... done
Setting REDIS_URL and restarting example-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 Data for Redis documentation.
We can see the add-on details at any time with the heroku addons
command:
$ heroku addons --app example-app
=== Resources for example-app
Plan Name Price
----------------- ------------------- ----------
heroku-redis:mini shining-calmly-4402 $3/month
=== Attachments for example-app
Name Add-on Billing App
----- ------------------- -------------
REDIS shining-calmly-4402 example-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
add-on:
$ heroku config --app example-app
REDIS_URL: redis://h:pa4kvrg6a3ah52g5akto82kil@ec2-54-204-3-133.compute-1.amazonaws.com:6569
Advanced Usage
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
Meaningful Names
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
--name
option:
$ heroku addons:create heroku-redis --app example-app --name important-redis
Creating important-redis... done, ($3/month)
Adding important-redis to example-app... done
Setting REDIS_URL and restarting example-app... done, v7
Now, wherever the add-on instance is identified, it will have a recognizable name:
$ heroku addons --app example-app
=== Resources for example-app
Plan Name Price
----------------- --------------- ----------
heroku-redis:mini important-redis $3/month
=== Attachments for example-app
Name Add-on Billing App
----- --------------- -------------
REDIS important-redis example-app
Sometimes, the name of the alias is 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
config var 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 example-app
.
Because add-on config vars are prefixed with the alias, we can choose
a non-default alias so that Celery easily uses our Key-Value Store instance as its
backend:
$ heroku addons:create heroku-redis --app example-app --name important-redis --as BROKER
Creating important-redis... done, ($3/month)
Adding important-redis to example-app... done
Setting BROKER_URL and restarting example-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 example-app
BROKER_URL: redis://h:pfcs5ilk6ksc7f5nt8v62qqf1ip@ec2-54-204-3-133.compute-1.amazonaws.com:6599
Not all add-ons support choosing your own alias.
Multiple Aliases/Attachments
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 Key-Value Store 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 example-app --as SESSION_STORE
Attaching important-redis as SESSION_STORE to example-app... done
Setting SESSION_STORE vars and restarting example-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 heroku
addons:attach BROKER --as SESSION_STORE
.
Once the attachment is created, we can see the extra alias in heroku addons
and the new config vars added as a result with heroku config
:
$ heroku addons --app example-app
=== Resources for example-app
Plan Name Price
----------------- --------------- ----------
heroku-redis:mini important-redis $3/month
=== Attachments for example-app
Name Add-on Billing App
------------- --------------- -------------
BROKER important-redis example-app
SESSION_STORE important-redis example-app
$ heroku config --app example-app
BROKER_URL: redis://h:pfcs5ilk6ksc7f5nt8v62qqf1ip@ec2-54-204-3-133.compute-1.amazonaws.com:6599
SESSION_STORE_URL: redis://h:pfcs5ilk6ksc7f5nt8v62qqf1ip@ec2-54-204-3-133.compute-1.amazonaws.com: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
same value.
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 Key-Value Store 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
application named example-tasker
. We can share the add-on with the second
application using any alias we like (or the default), but let’s reuse BROKER
so that we’ll understand its purpose in the future:
$ heroku addons:attach important-redis --app example-tasker --as BROKER
Attaching important-redis as BROKER to example-tasker... done
Setting BROKER vars and restarting example-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 example-app::BROKER --as SESSION_STORE --app example-tasker
.
Let’s look at the add-ons and config vars on our second application:
$ heroku addons -a example-tasker
=== Resources for example-tasker
There are no add-ons.
=== Attachments for example-tasker
Name Add-on Billing App
------ --------------- -------------
BROKER important-redis example-app
$ heroku config -a example-tasker
BROKER_URL: redis://h:pfcs5ilk6ksc7f5nt8v62qqf1ip@ec2-54-204-3-133.compute-1.amazonaws.com:6599
Notice how there are no add-on resources owned by the example-tasker
application but that it does have an attachment named BROKER
to the add-on
named important-redis
, which is billed to the app example-app
. Also
note that the BROKER_URL
shares a value with its kin on example-app
. If
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 Key-Value Store. 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 Key-Value Store instance easily enough:
$ heroku addons:create heroku-redis --app example-app
Creating sighing-nobly-1891... done, ($3/month)
Adding sighing-nobly-1891 to example-app... done
Setting REDIS_URL and restarting example-app... done, v11
We can even create a third:
$ heroku addons:create heroku-redis --app example-app
Creating cooling-carefully-7273... done, ($3/month)
Adding cooling-carefully-7273 to example-app... done
Setting HEROKU_REDIS_ROSE_URL and restarting example-app... done, v12
Note how the one installation used the default alias of REDIS
while the
other used 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 Key-Value Store instance for our session store, let’s replace
the SESSION_STORE
alias with one pointing to our new add-on:
$ heroku addons:attach sighing-nobly-1891 --as BROKER --app example-app
Attaching sighing-nobly-1891 as BROKER to example-app...
! sighing-nobly-1891 will overwrite BROKER_URL on example-app.
! To proceed, type "example-app" or re-run this command with --confirm example-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:
> example-app
Attaching sighing-nobly-1891 as BROKER to example-app... done
Setting BROKER vars and restarting example-app... done, v14
$ heroku addons --app example-app
=== Resources for example-app
Plan Name Price
----------------- ---------------------- ----------
heroku-redis:mini cooling-carefully-7273 $3/month
heroku-redis:mini important-redis $3/month
heroku-redis:mini sighing-nobly-1891 $3/month
=== Attachments for example-app
Name Add-on Billing App
----------------- ---------------------- -------------
BROKER sighing-nobly-1891 example-app
HEROKU_REDIS_ROSE cooling-carefully-7273 example-app
REDIS sighing-nobly-1891 example-app
SESSION_STORE important-redis example-app
$ heroku config --app example-app
BROKER_URL: redis://h:p5ip3vevv16shofgnkstglu65r9@ec2-54-204-3-133.compute-1.amazonaws.com:6609
HEROKU_REDIS_ROSE_URL: redis://h:pankbrfd3va8gejrrvep7r69j0@ec2-54-204-3-133.compute-1.amazonaws.com:6619
REDIS_URL: redis://h:p5ip3vevv16shofgnkstglu65r9@ec2-54-204-3-133.compute-1.amazonaws.com:6609
SESSION_STORE_URL: redis://h:pfcs5ilk6ksc7f5nt8v62qqf1ip@ec2-54-204-3-133.compute-1.amazonaws.com:6599
Notice that SESSION_STORE
, BROKER
, and 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 example-app
Removing REDIS attachment to sighing-nobly-1891 from example-app... done
Unsetting REDIS vars and restarting example-app... done, v15
$ heroku addons:destroy cooling-carefully-7273
! WARNING: Destructive Action
! This command will affect the app: example-app
! To proceed, type "example-app" or re-run this command with --confirm example-app
> example-app
Destroying cooling-carefully-7273 on example-app... done, ($3/month)
Removing vars for HEROKU_REDIS_ROSE from example-app and restarting... done, v16
Notice that the addons:detach
command removed an attachment alias (REDIS
) while addons:destroy
deprovisioned the add-on (cooling-carefully-7273
) as well as any associated attachments (such as HEROKU_REDIS_ROSE
).
Now everything looks the way we want with two distinct instances, one of which is
aliased as BROKER
to both of our applications:
$ heroku addons --app example-app
=== Resources for example-app
Plan Name Price
----------------- ------------------ ----------
heroku-redis:mini important-redis $3/month
heroku-redis:mini sighing-nobly-1891 $3/month
=== Attachments for example-app
Name Add-on Billing App
------------- ------------------ -------------
BROKER sighing-nobly-1891 example-app
SESSION_STORE important-redis example-app
$ heroku addons --app example-tasker
=== Resources for example-tasker
There are no add-ons.
=== Attachments for example-tasker
Name Add-on Billing App
------ --------------- -------------
BROKER important-redis example-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 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:attach
to replace an alias that already exists so you can change which instance your application uses. - Replace a RedisCloud instance with a Heroku Key-Value Store 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.
Details
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 |
---|---|---|---|
Heroku Postgres | database | _url | DATABASE_URL |
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_cache
and its default alias isIRON_CACHE
, while Heroku Postgres’ service name isheroku-postgresql
but its chosen default alias isDATABASE
notHEROKU_POSTGRESQL
).A generated alias based on the add-on service name and a random color.
For example, when
DATABASE
is already taken, a name likeHEROKU_POSTGRESQL_CYAN
is chosen for Heroku Postgres; and whenREDISCLOUD
is already taken, a name likeREDISCLOUD_BLUE
is 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
app-name::ALIAS
.
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
the command 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 in some cases, such as changing plans or in the event of a failure of underlying infrastructure causing 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’s therefore important that applications don’t use hard-coded add-on config var values in code or configuration or cache config var values during their build, in order to keep interruption of service as minimal as possible. Config vars must always dynamically be read at runtime or during application startup instead.