Databases
Leash provides managed PostgreSQL databases. When you deploy an app that uses a database, the CLI detects it and offers to create one for you.
Automatic Detection
The CLI detects database dependencies in your package.json, requirements.txt, go.mod, and other manifest files. If it finds PostgreSQL packages, it offers to provision a database.
| Dependency | Language |
|---|---|
pg | Node.js |
prisma | Node.js / TypeScript |
psycopg / psycopg2 | Python |
pgx | Go |
Deploy Flow
When a database dependency is detected during deploy, the CLI gives you three choices:
$ leash deploy
✓ Detected: flask (python)
⚠ Your app uses PostgreSQL (psycopg)
Options:
[1] Create a Leash database (included on Growth and above)
[2] Paste your own database URL
[3] Skip — I'll configure it later
Choice (1/2/3): 1
✓ Database created — DATABASE_URL injected
How It Works
- Each app gets its own isolated PostgreSQL database and user
DATABASE_URLis automatically injected as an environment variable- Your ORM (Prisma, SQLAlchemy, etc.) creates tables on first connection
- Daily automated backups with 7-day retention
Instance sizing
Each provisioned database is a small Postgres instance suitable for running one app: low connection count, short query budget, and modest storage. We tune the exact resources to the platform's current defaults rather than publishing a per-plan matrix here; the dashboard shows the live limits for your database after it's created.
Need a bigger instance, dedicated resources, or a different region? Use “Bring your own database” below and point Leash at any external Postgres.
Applying a schema
Keep your schema in source. Two files do the work:
db/schema.sql— full source of truth for the schema (re-runnable from a clean DB).db/migrations/<timestamp>_<name>.sql— append-only, one file per change after the first deploy.
1. Write the initial schema
create table if not exists notes (id uuid primary key default gen_random_uuid(),body text not null,user_id text not null,created_at timestamptz not null default now());create index if not exists notes_user_id_idx on notes (user_id);
2. Apply it locally
With leash dev running, your app has DATABASE_URL in its env. Apply the schema directly with psql:
$ leash dev -- bash -c 'psql "$DATABASE_URL" -f db/schema.sql'
CREATE TABLE
CREATE INDEX
Or use whichever migrator your stack prefers — Prisma (prisma db push / prisma migrate dev), Knex, Alembic, golang-migrate, sqlx-cli. They all read DATABASE_URL.
3. Ship migrations alongside code
For incremental changes after the first deploy, add a new file to db/migrations/:
alter table notesadd column if not exists color text not null default 'gray';
Apply it with the same migrator. Migrations are append-only — never edit a migration that's been applied to a deployed environment. To revert, create a new migration that undoes the change.
Run migrations as part of your deploy process — most stacks support a release-phase hook (e.g. prisma migrate deploy for Node, alembic upgrade head for Python, migrate up for Go).
Common Issues
- "too many connections" — Use connection pooling (PgBouncer or app-level). Close connections after each request.
- "canceling statement due to statement timeout" — Long-running query hit the per-statement timeout. Optimize the query, add indexes, or paginate results.
- "connection refused" — DATABASE_URL only works from apps deployed on Leash. It uses an internal socket connection and is not accessible externally.
Bring Your Own Database
Already using an external database? Choose option [2] during deploy or set the connection string manually.
Set the connection string in your app's Environment tab on the dashboard. Use the appropriate variable name for your database:
Supabase
Set DATABASE_URL to your Supabase connection string.
Neon
Set DATABASE_URL to your Neon connection string.
MongoDB Atlas
Set MONGODB_URI to your Atlas connection string.
Redis (Upstash / Redis Cloud)
Set REDIS_URL to your Redis connection string.