How to pull in Heroku postgres credentials for next-auth?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When NextAuth, now part of Auth.js, stores users or sessions in Heroku Postgres, you do not hand-copy the database username and password into your authentication code. Heroku provides the connection string as an environment variable, and your database client reads it at runtime. Once that wiring is correct, the authentication adapter can use the same database connection as the rest of your app.
Heroku Exposes the Database Through DATABASE_URL
Provisioning Heroku Postgres creates a config var named DATABASE_URL. That one value contains the host, port, username, password, and database name in PostgreSQL URL form.
You can inspect it from the CLI:
That value should stay in the environment. Do not paste it into source files or hardcode it inside your Next.js config. Heroku can rotate or replace database credentials, so code should always read the current value from process.env.
The usual flow is:
- Heroku manages the credential
- your ORM reads
DATABASE_URL - NextAuth uses the ORM adapter
There is no special "NextAuth database secret" that replaces the standard database URL.
Wire Prisma to the Environment Variable
Prisma is one of the most common choices for a NextAuth database adapter. In that setup, the Prisma schema points to DATABASE_URL:
Then create one shared Prisma client:
This pattern avoids opening a fresh Prisma client on every hot reload in development.
Pass Prisma Into NextAuth
Once Prisma can connect to Heroku Postgres, the auth layer becomes simple:
In other words, NextAuth does not pull credentials from Heroku directly. Prisma does that by reading DATABASE_URL, and the adapter reuses that connection path.
Local Development Needs Its Own Environment Value
Heroku sets the variable in the deployed runtime, but your laptop does not know it unless you provide it. For local testing, you can copy the value into .env.local:
Sometimes local drivers need an explicit SSL parameter:
That is a local environment concern, not something that should be hardcoded into application logic.
Apply the Database Schema
Even with the correct credentials, authentication will still fail if the required tables do not exist. After wiring Prisma to Heroku Postgres, generate the client and apply migrations:
If sign-in fails after deployment, check whether the User, Account, Session, and VerificationToken tables were actually created in the same database that DATABASE_URL points to.
A Practical Debugging Order
When the app cannot authenticate against Heroku Postgres, check the chain in order:
- confirm the Heroku app has a Postgres add-on
- confirm
DATABASE_URLexists - confirm Prisma uses
env("DATABASE_URL") - confirm the deployed app sees the expected value
- confirm migrations ran against that database
This sequence avoids a lot of wasted effort. Many "NextAuth cannot see my Heroku database" reports turn out to be "Prisma was connected to the wrong environment" or "the schema never got applied."
Common Pitfalls
One common mistake is copying the full database URL into source code. That creates a secret-management problem and breaks as soon as Heroku changes the credential.
Another mistake is assuming NextAuth wants its own Heroku-specific connection setting. In a Prisma-based setup, the adapter simply uses Prisma, and Prisma uses DATABASE_URL.
Developers also sometimes run migrations locally while the deployed app points at Heroku Postgres. The connection works, but the production database is missing the auth tables.
Finally, do not forget local SSL behavior. Heroku Postgres expects encrypted connections, so some local tools need sslmode=require even when the deployed platform already handles the details.
Summary
- Heroku Postgres exposes its credentials through
DATABASE_URL. - Your ORM should read
process.env.DATABASE_URLat runtime. - With Prisma, use
url = env("DATABASE_URL")and let the NextAuth adapter reuse that connection. - Local development may need the same URL in
.env.local, sometimes withsslmode=require. - If auth fails after connecting, verify that the database schema was actually created in the Heroku database.

