env.dev

DATABASE_URL

Sensitive

A universal database connection string following the URI format protocol://user:password@host:port/database. Used by ORMs (Prisma, Sequelize, SQLAlchemy, ActiveRecord) and database drivers as the primary connection configuration. Supports PostgreSQL, MySQL, SQLite, and other databases.

Last updated:

DATABASE_URL packs an entire database connection into one URI: protocol://user:password@host:port/database?options. The Twelve-Factor App convention popularized it, and now Prisma, SQLAlchemy, Rails (via DATABASE_URL overriding database.yml), Django (with dj-database-url), and most PaaS providers read it directly. Heroku, Railway, Render, and Supabase inject it for you. The scheme matters: 'postgresql://' and 'postgres://' both work for Postgres, but Prisma and some libraries are picky, and 'mysql://' vs 'mysql2://' differ across Ruby and Node ecosystems.

Provider
Databases
Category
connection
Set by
Set manually in application configuration or provided by PaaS platforms (Heroku, Railway, Render)
Example
postgresql://user:password@localhost:5432/mydb?sslmode=require
Security: DATABASE_URL almost always contains the database password in plaintext. Keep it out of source control, scrub it from error logs and crash reporters (it is a common accidental leak in stack traces), and inject it from a secrets manager in production. If the password contains special characters like @, :, /, or #, URL-encode them or the URI will be parsed wrong — a '@' in a password splits the host incorrectly.
Gotcha: Connection pooling bites here. Serverless platforms (Lambda, Vercel, Cloud Functions) open a new connection per invocation and quickly exhaust Postgres's max_connections. Point DATABASE_URL at a pooler (PgBouncer, Supabase's pooled port 6543, Prisma Accelerate) for the app, and keep a separate direct URL for migrations.

How to set DATABASE_URL

bash (Postgres)

export DATABASE_URL='postgresql://user:pass@localhost:5432/mydb?sslmode=require'

docker-compose

services:
  app:
    environment:
      DATABASE_URL: postgresql://user:pass@db:5432/mydb
  db:
    image: postgres:17

URL-encode a special character in the password

# password p@ss:word -> p%40ss%3Aword
postgresql://user:p%40ss%3Aword@host:5432/db

Frequently Asked Questions

My password has special characters and the connection fails. Why?

A DATABASE_URL is a URI, so characters like @ : / ? # in the password break parsing — a literal @ is read as the user/host separator. URL-encode them (@ → %40, : → %3A, / → %2F) or the driver connects to the wrong host or rejects the string.

Why do I get 'too many connections' on serverless?

Each serverless invocation can open its own database connection, blowing past Postgres's connection limit under load. Connect through a pooler (PgBouncer, Supabase pooled port, Prisma Accelerate) via DATABASE_URL, and use a separate direct connection only for migrations.

Was this helpful?

Stay up to date

Get notified about new guides, tools, and cheatsheets.

Browse all 242 environment variables →