# Databases and backups

> Create a database in an environment and link it to a service; Unrent writes the connection settings into the service’s secrets. Add an S3-compatible bucket at another provider for backups, then run restore drills to prove they restore.

URL: https://unrent.dev/docs/databases/

## Create and link

Pick the engine (Postgres 17 or 18, MySQL 8.4, Valkey 9.1), a name and the server. Passwords are generated on the server. **Link** writes these into the service’s config, ready to apply:

Variables a link adds

| Engine | Plain | Secret |
| --- | --- | --- |
| Postgres | `PGHOST` `PGPORT` `PGDATABASE` `PGUSER` | `PGPASSWORD` `DATABASE_URL` |
| MySQL | `MYSQL_HOST` `MYSQL_PORT` `MYSQL_DATABASE` `MYSQL_USER` | `MYSQL_PASSWORD` `DATABASE_URL` |
| Valkey | `REDIS_HOST` `REDIS_PORT` `REDIS_USERNAME` | `REDIS_PASSWORD` `REDIS_URL` |

Databases are reachable only from the environment’s network on that server, by their name (for example `orders:5432`); no port is published. **Rotate** sets a new password and applies it to every linked service.

## Off-site storage

Backups go to the server’s own disk until you add a storage target: Amazon S3, Cloudflare R2, Backblaze B2 or any S3-compatible service. The keys are sealed in your browser to the server.

Adding, changing or deleting a target is a **policy** change: it needs an admin and an approver’s passkey, verified on the server. Unrent then writes, reads and deletes a probe object; a target is usable only once that passes.

## Backups

- **Postgres:** continuous WAL archiving (at least once a minute) and a verified base backup every 24 hours
- **MySQL:** a nightly `mysqldump`; **Valkey:** a nightly RDB snapshot. The 14 newest are kept
- A backup counts only after it has been listed and read back in the bucket
- `backup_late` and `backup_failing` alerts tell you when that stops happening

## Drills, restores and promote

**Run drill** restores a backup into a scratch copy and checks it: for Postgres, rows written before a moment are there and none after, `pg_amcheck` passes and every database accepts connections. You see the result, the restore time and the data that would have been lost.

**Restore** creates a read-only scratch copy at a time you choose (or the latest), for 1 to 48 hours, next to production. Connect to it to check or copy data.

For Postgres, **Promote** swaps a scratch copy into production. It is destructive, so it needs a passkey; the old production database is stopped and kept for up to 30 days. If any step fails, the swap is undone.

> **Coming:** Drills on a weekly schedule, one-click undo of a promote, promote for MySQL and Valkey, and client-side backup encryption.
