# Databases

Add Postgres, MySQL, Redis or MongoDB to a project in one click: **+ Create → Database** on the project's canvas, then the one you want. It sits on the canvas beside the apps that use it, set up the way a database should be:

- **The engine's official image** on its current major version: `postgres:17`, `mysql:8.4`, `redis:7` or `mongo:8`. A new deploy picks up its patch releases; nothing moves it to a new major version by surprise.
- **A generated password**, kept as a secret. MySQL and MongoDB get a separate root password, so the app's never has root's powers (MongoDB's app user owns its own database, `app`, and nothing else).
- **A disk of its own**: 1 GB for Postgres and Redis, 2 GB for MySQL and MongoDB, billed by its size ($0.10 a GB a month). Make it bigger as it runs, or let it grow by itself, under **Volumes**.
- **Private and always running.** Only the project's own services reach it, and it never sleeps, so an app's first query doesn't wait for it to wake.
- **In the region you choose**, where there's more than one: it runs on one server there, and stays there with its disk. See [choosing regions](/docs/servers#choosing-regions).
- **Backed up from the start**: a [snapshot](/docs/backups) every day, the last week of them kept, and a copy off the server where the platform has somewhere to put one.

## Connecting an app

Open the database and its **Connect** tab, choose your app and click **Connect**. The app gets one variable and is deployed with it:

| Database | Variable | Looks like |
| --- | --- | --- |
| Postgres | `DATABASE_URL` | `postgres://app:…@postgres:5432/app` |
| MySQL | `DATABASE_URL` | `mysql://app:…@mysql:3306/app` |
| Redis | `REDIS_URL` | `redis://default:…@redis:6379` |
| MongoDB | `MONGODB_URI` | `mongodb://app:…@mongodb:27017/app` |

What's stored on the app is a [reference](/docs/variables-and-secrets), `${{postgres.DATABASE_URL}}`, not a copy of the URL. The app follows the database: change its password and the app has the new one with its next deploy, and the password is never pasted anywhere it could go stale.

To use it in a variable of your own (a framework that wants the host and port apart, say), reference what you need: `${{postgres.HOST}}`, `${{postgres.PORT}}`, `${{postgres.POSTGRES_PASSWORD}}`.

A second database of the same kind gets a name of its own: `postgres-2`, with its own password and its own URL.

## Working with it

A prompt in it, a GUI client or a migration from your own machine, and backups: [working with a database](/docs/database-access) and [backups](/docs/backups).

## Good to know

- **It's sandboxed like everything else.** It runs in a [virtual machine](/docs/security) of its own, with its own kernel, the same as your apps, and so does its terminal. That matters more for a database than it might seem: whoever has its password can run programs in it (Postgres's `COPY … FROM PROGRAM` is a shell). It costs a little speed on lots of small writes — a commit takes a couple of milliseconds — and a first start takes twice as long.
- **Its size.** Postgres and Redis get xs (a quarter of a core, 256 MB: $1.50 a month), MySQL and MongoDB m (a core, 1 GB: $6; they hold a lot before they have any data). It never sleeps, so it's billed its size all month. Make it bigger under **Scaling** if it restarts under load: it's given the new size as it runs.
- **MongoDB runs on its own, not as a replica set**, so it has no multi-document transactions. Mongoose and MongoDB's drivers work as they are; Prisma's MongoDB connector needs a replica set and doesn't, yet.
- **One server.** A database lives on one server, with its disk. There's no replica or automatic failover yet: if that server is down, so is the database, and its snapshots are what bring it back somewhere else.
- **Coding agents** can do the same with the `add_database` and `connect_database` tools.
