# Connect a managed database

Choose an environment-managed database for access within one environment, or Managed Postgres for logical databases that can attach to services across the product's environments. Configure the connection, then redeploy the consuming service.

## Before you start

- Have a product, an environment and a service that needs a database.
- Choose the database model before provisioning; their connection and restore workflows differ.
- For MCP, use a product-scoped token with Deployment `write` for provisioning, connections, backups and resizing; `read` for inspection; and `admin` for restore or deletion.

## 1. Provision an environment database

On the environment canvas, choose **Add service → Databases**, or call [`deployment_managed_service_provision`](/reference/mcp-tools/deployment_managed_service_provision). Set the name and engine; choose a version and storage if the defaults do not fit.

| Engine | Versions | Default |
|---|---|---|
| PostgreSQL | 15, 16, 17 | 16 |
| MySQL | 8.0, 8.4 | 8.4 |
| Redis | 7, 8 | 7 |
| MongoDB | 7, 8 | 8 |

Storage defaults to 5 GiB, with a range of 1–1024 GiB. The initial database name defaults to `app` for PostgreSQL, MySQL and MongoDB. The generated or chosen slug uses lowercase letters, digits and dashes, starts with a letter, and must be unique within the environment.

Wait for `provisioning` to become `ready`. If it becomes `provisioning_failed`, read the error and retry with [`deployment_managed_service_reconcile`](/reference/mcp-tools/deployment_managed_service_reconcile). Use [`deployment_managed_service_types`](/reference/mcp-tools/deployment_managed_service_types) to inspect available engines and versions.

## 2. Connect the service

Open the database node's **Connect** view, or call [`deployment_managed_service_connect_info`](/reference/mcp-tools/deployment_managed_service_connect_info). Copy the reference for the connection value your library expects. Nothing is injected automatically.

For a PostgreSQL database with slug `postgres`, set service variable `DATABASE_URL` to `${{postgres.DATABASE_URL}}`. Replace the slug with yours and mark the service variable as secret. All engines authenticate; passwords and full connection strings are secret values.

| Engine | Published keys |
|---|---|
| PostgreSQL | `HOST`, `PORT`, `USER`, `PASSWORD`, `DATABASE`, `URL`, `DATABASE_URL`, `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE` |
| MySQL | `HOST`, `PORT`, `USER`, `PASSWORD`, `DATABASE`, `URL`, `DATABASE_URL`, `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DATABASE`, `MYSQL_URL` |
| Redis | `HOST`, `PORT`, `PASSWORD`, `URL` |
| MongoDB | `HOST`, `PORT`, `USER`, `PASSWORD`, `DATABASE`, `URL`, `MONGODB_URI` |

Aliases carry the same values as the corresponding plain keys. An environment-managed database has no public address; connect from a service in the same environment.

## 3. Redeploy and verify it works

Redeploy the consuming service to resolve its [variables](/ship/deployment/variables). Check that the deployment becomes `Active`, then run an application read/write operation and read the result back. Inspect service and database logs if the connection fails; do not print credentials while diagnosing it.

## Managed Postgres

For a product-level instance, use **Databases → Add database**, or [`deployment_cloud_sql_instance_create`](/reference/mcp-tools/deployment_cloud_sql_instance_create).

1. Give the instance a label. Choose Postgres 16, 17 or 18 (default 18), and tier `db-custom-1-3840` (default), `db-custom-2-7680` or `db-custom-4-15360`. Creating the first Managed Postgres database from the environment canvas creates a `default` instance if needed.
2. Create a logical database with [`deployment_cloud_sql_database_create`](/reference/mcp-tools/deployment_cloud_sql_database_create). Its label is optional; actual database and role names are generated.
3. Once the instance and database are ready, attach the database with [`deployment_cloud_sql_database_attach`](/reference/mcp-tools/deployment_cloud_sql_database_attach). Supply the database, service and environment IDs. One database can attach to several services.
4. Redeploy each attached service and verify an application read/write operation.

Attachment creates secret service variables `DATABASE_URL`, `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD` and `PGDATABASE`. Passwords are not returned in database or instance views. Detaching removes those six variables; deleting a logical database detaches it from every service first.

## Back up and restore

| Model | Backup behavior | Restore scope |
|---|---|---|
| Environment-managed database | Ready databases are backed up daily at 03:00 UTC. On-demand backups run while the database serves. All snapshots, including manual ones, expire after seven days. | Replaces that database's contents in place; start from `ready` or `stopped` |
| Managed Postgres | Nightly backups with point-in-time recovery; seven days of backups and transaction logs. On-demand backups keep the instance available. | Restoring a backup run replaces the entire instance, including every logical database, and makes it unavailable for several minutes |

Before restoring, take a fresh backup if current data still matters. In **Backups**, choose a completed snapshot or backup run. MCP uses [`deployment_managed_service_restore`](/reference/mcp-tools/deployment_managed_service_restore) for an environment database or [`deployment_cloud_sql_instance_restore`](/reference/mcp-tools/deployment_cloud_sql_instance_restore) for an instance. The Managed Postgres dialog asks you to type the instance label.

After restore, wait for readiness and verify expected records through the application. Export data yourself if it must outlive the seven-day window.

An environment database's **last backup** timestamp is recorded after a snapshot is confirmed ready and can lag by up to a day. An empty timestamp means no backup is recorded yet. Managed Postgres reports backup/PITR settings with their observation time; an unobserved blank value does not mean disabled.

## Resize, stop or delete

Environment database **Settings** provides storage growth, stop, start and delete. Resize requires `ready` and cannot shrink storage. Stop requires `ready`, preserves storage and credentials, and prevents connections; stop dependent workloads first. Start resumes a stopped database with its data. Delete removes the database and storage.

Other lifecycle states include `stopping`, `stopped`, `starting`, `resizing`, `backing_up`, `restoring` and `deleting`. Wait for an action to finish before starting an incompatible one.

Managed Postgres instances can move to another supported tier. Instance deletion is refused while any logical database or attachment remains. Use the [generated reference](/reference/openapi/deployment) for exact lifecycle operation inputs.
