Last updated April 21, 2026
Heroku Postgres is accessible from many different programming languages and frameworks.
Heroku Postgres & SSL
Heroku Postgres requires SSL connections using TLS v1.2 or higher.
Most clients will connect over SSL by default, but depending on the client it’s necessary to set the sslmode=require parameter on a Postgres connection. Add this parameter in code rather than editing your add-on’s config var directly.
Connection Permissions
The default credential on Heroku Postgres databases corresponds to a permissive role that’s one step below the superuser. This credential is the owner of the database.
You can also create and manage a custom credential that allows connecting to a Heroku Postgres database with a more limited set of privileges.
Multiple Schemas
Heroku Postgres supports creating and using multiple database schemas and doesn’t place specific limits on the number of schemas you can create.
The most common use case for using multiple schemas in a database is building a software-as-a-service application wherein each customer has their own schema. While this technique seems compelling, we strongly recommend against it as it’s known to cause operational problems. For instance, even a moderate number of schemas (> 50) can severely impact the performance of PostgreSQL’s logical backup tooling, such as pg_dump or Heroku PGBackups.
External Connections (Ingress)
In addition to being accessible from the Heroku runtime, Heroku Postgres databases can be accessed directly by clients running outside of Heroku, on your local computer or elsewhere.
All connections to Heroku Postgres require SSL: sslmode=require.
Use your database connection string to connect to your Heroku Postgres database from any external service. You can retrieve your database connection string via the CLI or the Heroku Dashboard.
Run the heroku pg:credentials:url CLI command to obtain your database connection details:
$ heroku pg:credentials:url DATABASE -a example-app
Connection information for default credential.
Connection info string:
"dbname=d9am5ro65cprs0 host=ec2-51-69-101-86.eu-west-1.compute.amazonaws.com port=5432 user=u42424246psem9 password=... sslmode=require"
Connection URL:
postgres://u42424246psem9:...@ec2-52-19-101-86.eu-west-1.compute.amazonaws.com:5432/d9fm5ro65cprs0
To obtain your database’s connection string through the dashboard:
- Open a Heroku Postgres database from the
Datastorestab, or your app’sResourceslist. - Select the
Credentialstab. - Click the
Editbutton for a credential. - Show or copy the database connection string from the
URIsection.
Heroku Postgres automatically includes your database add-on’s connection strings as config vars on your app. You can also check your app’s config vars through the Heroku CLI or the Heroku Dashboard to obtain your database’s connection string:
$ heroku config | grep postgres
HEROKU_POSTGRESQL_YELLOW_URL: postgres://u42424246psem9u:...@ec2-51-69-101-86.eu-west-1.compute.amazonaws.com:5432/d9fm5ro65cprs0
You can’t directly access Heroku Postgres databases on the Private and Shield-tier plans from outside their Private or Shield space. See Heroku Postgres and Private Spaces: Connecting to the Database for external access features and instructions.
If you get the error The authentication type 10 is not supported. or SCRAM authentication is not supported by this driver. while connecting to your Essential database, see this Help article.
Connecting in Java
There are a variety of ways to create a connection to a Heroku Postgres database, depending on the Java framework in use. In most cases, the environment variable JDBC_DATABASE_URL can be used directly as described in the article Connecting to Relational Databases on Heroku with Java. For example:
private static Connection getConnection() throws URISyntaxException, SQLException {
String dbUrl = System.getenv("JDBC_DATABASE_URL");
return DriverManager.getConnection(dbUrl);
}
When it isn’t possible to use the JDBC URL (usually because custom buildpack is being used), you must use the DATABASE_URL environment URL to determine connection information. Some examples are provided below.
By default, Heroku attempts to enable SSL for the PostgreSQL JDBC driver by setting the property sslmode=require globally. If you’re building the JDBC URL yourself (such as by parsing the DATABASE_URL), we recommend explicitly adding this parameter.
It’s also important that you use a version of the Postgres JDBC driver version 9.2 or greater. For example, in Maven add the following to your pom.xml:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.1</version>
</dependency>
Examples of all outlined connection methods here are available on GitHub at: https://github.com/heroku/devcenter-java-database
JDBC
Create a JDBC connection to Heroku Postgres by parsing the DATABASE_URL environment variable.
private static Connection getConnection() throws URISyntaxException, SQLException {
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath() + "?sslmode=require";
return DriverManager.getConnection(dbUrl, username, password);
}
Spring/XML
The following Spring XML configuration snippet creates a BasicDataSource from the DATABASE_URL. It can be used with Hibernate, JPA, etc:
<bean class="java.net.URI" id="dbUrl">
<constructor-arg value="#{systemEnvironment['DATABASE_URL']}"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + ':' + @dbUrl.getPort() + @dbUrl.getPath() + '?sslmode=require' }"/>
<property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
<property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>
</bean>
Spring/Java
Alternatively you can use Java for configuration of the BasicDataSource in Spring:
@Configuration
public class MainConfig {
@Bean
public BasicDataSource dataSource() throws URISyntaxException {
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath() + "?sslmode=require";
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setUrl(dbUrl);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
return basicDataSource;
}
}
The DATABASE_URL for the Heroku Postgres add-on follows this naming convention:
postgres://<username>:<password>@<host>/<dbname>
However the Postgres JDBC driver uses the following convention:
jdbc:postgresql://<host>:<port>/<dbname>?sslmode=require&user=<username>&password=<password>
Notice the additional ql at the end of jdbc:postgresql? Due to this difference, you must hardcode the scheme to jdbc:postgresql in your Java class or your Spring XML configuration.
Remote Connections
You can connect to your Heroku Postgres database remotely for maintenance and debugging purposes. However, doing so requires that you use an SSL connection. Your JDBC connection URL must include the following URL parameter:
sslmode=require
If you leave off sslmode=require and attempt to connect to a Heroku Postgres database, you receive a connection error.
You must add this parameter in code rather than editing the database’s config var directly. Automated events such as failovers or credential rotations can modify the config var, overwriting your edits.
See Connecting to Relational Databases on Heroku with Java for more information.
Connecting in Ruby
To use PostgreSQL as your database in Ruby applications you must include the pg gem in your Gemfile.
gem 'pg'
Run bundle install to download and resolve all dependencies.
If you’re using the pg gem to connect to your Postgres database from a Heroku dyno, and haven’t specified an sslmode in your configuration or code, the gem defaults to sslmode=prefer. If you use sslmode=prefer, the PostgreSQL client attempts to create a SSL connection to the server first.
Connecting in Rails
See Rails Database Connection Behavior for more information on connecting to Heroku Postgres in Rails.
Connecting in JRuby
To use PostgreSQL as your database in JRuby applications you must include the activerecord-jdbcpostgresql-adapter gem in your Gemfile.
gem 'activerecord-jdbcpostgresql-adapter'
Run bundle install to download and resolve all dependencies.
If using Rails, follow the instructions for Connecting with Rails.
Connecting in Python
To use PostgreSQL as your database in Python applications you must use the psycopg2 package.
$ pip install psycopg2-binary
And use this package to connect to DATABASE_URL in your code.
import os
import psycopg2
DATABASE_URL = os.environ['DATABASE_URL']
conn = psycopg2.connect(DATABASE_URL, sslmode='require')
Connecting with Django
Install the dj-database-url package using pip.
$ pip install dj-database-url
Be sure to add psycopg2-binary and dj-database-url to your requirements.txt file as well.
To parse the values of the DATABASE_URL environment variable and convert them to something Django can understand, add the following to the bottom of settings.py:
import dj_database_url
DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)
Connecting in Go
Go apps can connect to Heroku Postgres by providing the pq Postgres database driver to their query interface of choice (such as the standard database/sql). Your app will use the query interface, rather than using the driver directly.
Standard Usage (database/sql)
$ cd <app>
$ dep ensure -add github.com/lib/pq
import (
"database/sql"
_ "github.com/lib/pq"
)
...
func main() {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
...
}
SSL is required to connect to Heroku Postgres.
pq automatically sets sslmode=require,
but if you use another library, you must configure SSL explicitly.
Beyond the Standard Lib
For lower-level access to Postgres, you can use pgx.
For time-saving extensions to database/sql, you can use sqlx.
Connecting in PHP
General Considerations
If a framework or library cannot natively handle database connection strings formatted as URLs, use the parse_url() function to parse the DATABASE_URL environment variables into individual values for user, pass, host, port, and database name.
The leading slash must be trimmed from the path component, since it represents the database name.
$db = parse_url(getenv("DATABASE_URL"));
$db["path"] = ltrim($db["path"], "/");
The resulting associative array in $db contains the information from the URL, as documented, with the database name available through the “path” key.
Connecting with PDO
A DSN must be constructed to connect using PDO:
$db = parse_url(getenv("DATABASE_URL"));
$pdo = new PDO("pgsql:" . sprintf(
"host=%s;port=%s;user=%s;password=%s;dbname=%s",
$db["host"],
$db["port"],
$db["user"],
$db["pass"],
ltrim($db["path"], "/")
));
Connecting with the pgsql Extension
The pgsql extension passes connection strings directly to the underlying libpq library, which supports URL-style connection strings, so the DATABASE_URL environment variable can be used directly:
$conn = pg_connect(getenv("DATABASE_URL"));
Connecting with the pq Extension
The pq extension passes connection strings directly to the underlying libpq library, which supports URL-style connection strings, so the DATABASE_URL environment variable can be used directly:
$conn = new pq\Connection(getenv("DATABASE_URL"));
Connecting with Laravel
The config/database.php file returns an array of database connection info to the framework; it can simply be amended to call parse_url() on the DATABASE_URL environment variable first, and return the extracted data:
$DATABASE_URL = parse_url(getenv("DATABASE_URL"));
return [
// …
'connections' => [
// …
'pgsql' => [
'driver' => 'pgsql',
'host' => $DATABASE_URL["host"],
'port' => $DATABASE_URL["port"],
'database' => ltrim($DATABASE_URL["path"], "/"),
'username' => $DATABASE_URL["user"],
'password' => $DATABASE_URL["pass"],
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'require',
],
// …
],
// …
];
Connecting with Symfony 3
The DATABASE_URL environment variable can be referenced in config.yml; Symfony’s DoctrineBundle automatically parses the URL’s contents.
Connecting with Symfony 4 and Later
Symfony 4 and later versions automatically pick up the DATABASE_URL environment variable without further configuration.
Connecting in Node.js
Install the pg NPM module as a dependency:
$ npm install pg
Then, connect to process.env.DATABASE_URL:
const { Client } = require('pg');
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});
client.connect();
client.query('SELECT table_schema,table_name FROM information_schema.tables;', (err, res) => {
if (err) throw err;
for (let row of res.rows) {
console.log(JSON.stringify(row));
}
client.end();
});
Alternatively, you can omit the ssl configuration object if you specify the PGSSLMODE config var: heroku config:set PGSSLMODE=no-verify.