# Self-managed relational databases

Source: https://docs.quake.ai/docs/databases/concepts/self-managed-relational-databases
Markdown: https://docs.quake.ai/docs/databases/concepts/self-managed-relational-databases.md
> How a PostgreSQL or MySQL/MariaDB deployment on Quake AI composes a compute instance, a Block Storage data volume, a private network, and a security group.

---

# Self-managed relational databases

A database on Quake AI is a composition of four IaaS resources: a compute instance that runs the engine process, a Block Storage volume that holds the data directory, a private network that carries client traffic, and a security group that limits which addresses reach the database port. No separate database API sits above them. You operate the engine the same way you would on any Linux host.

<Figure caption="A database deployment: the application instance reaches the database over the private network, and the engine writes to an attached Block Storage volume">

```d2
direction: right

project: Quake AI project {
  app: Application instance

  net: Private network {
    sg: Security group
  }

  db: Database instance {
    engine: PostgreSQL or MariaDB
  }

  vol: Data volume {shape: cylinder}

  app -> net.sg: 5432 / 3306
  net.sg -> db.engine: allowed CIDRs only
  db.engine -> vol: data directory
}
```

</Figure>

## The compute instance

The instance runs the engine, its configuration, and the backup script. Its flavor sets the CPU and memory available to the engine, and its image sets the package versions cloud-init installs. Both database templates default to Ubuntu 24.04, so the SSH user is `ubuntu` and the engine comes from the distribution packages.

The instance is replaceable. Everything that must survive instance replacement belongs on the data volume or on a copy you keep outside the instance.

## The data volume

Both templates attach a separate Block Storage volume (50 GB by default) and mount it at the engine's data directory: `/var/lib/postgresql` for PostgreSQL, `/var/lib/mysql` for MySQL and MariaDB. Keeping the data directory off the root disk means you can extend the volume as the database grows, snapshot it independently of the instance, and detach it when you rebuild the host.

Volumes extend but do not shrink, so size the initial volume with headroom. [Volumes](/docs/block/concepts/volumes) covers sizing, snapshots, clones, and the crash-consistency boundary that applies when you snapshot a volume an engine is actively writing to.

## The private network

Neither database template allocates a floating IP. The database instance receives a private address on a subnet inside the project (`192.168.40.0/24` for the PostgreSQL template, `192.168.50.0/24` for the MySQL/MariaDB template), and applications on the same network connect to that address directly. Administrative access arrives through a bastion or VPN. [Database networking and access](/docs/databases/concepts/database-networking-and-access) covers the paths in detail.

## The security group

A security group on the database port carries the access decision. Both templates take an `allowed_cidrs` variable and open the engine's port to those ranges: `5432` for PostgreSQL, `3306` for MySQL and MariaDB. Narrow the range to the application subnet rather than the whole private network when the application tier has its own subnet.

## Engine choice

| Engine | Template | What cloud-init installs |
| --- | --- | --- |
| PostgreSQL | [Self-Managed PostgreSQL](/resources/iac-templates/self-managed-postgres) | PostgreSQL at the `pg_version` you set (16 by default), the `db_name` database, the `db_user` role, local WAL archiving, and a nightly `pg_dumpall` |
| MySQL or MariaDB | [MySQL/MariaDB Database](/resources/iac-templates/mysql-database) | The package named by `db_engine_package` (`mariadb-server` by default), the `db_name` database, the `db_user` role, and a nightly `mysqldump --all-databases` |

Both templates require you to set `db_password` at apply time; neither ships a default password.

Two other templates embed a database inside a larger composition: [WordPress + MySQL on Compute](/resources/iac-templates/wordpress-mysql) pairs WordPress with a MariaDB instance, and [Full-Stack Application](/resources/iac-templates/full-stack-app) runs MariaDB as the private data tier behind web and application tiers.

## What you operate

Quake AI keeps the instance running, the volume attached, and the network path available. The engine and its data are yours:

- Engine configuration, tuning, and major-version upgrades
- Database users, roles, and grants beyond the one the template creates
- Schema changes and query performance
- Backup scheduling, retention, and restore drills
- Copying dumps off the data volume so recovery survives losing that volume
- Patching the operating system on the database instance

[Shared responsibility](/docs/security/shared-responsibility) sets out the same split across the rest of the platform.

## Availability and scale

Both templates deploy a single database instance. A single instance means maintenance, an engine crash, or a host failure interrupts the database until it comes back. Applications that cannot absorb that interruption need an availability design at the application layer: engine-level replication you configure yourself, a read replica you provision as a second instance, or a failover procedure you rehearse. [High availability](/docs/compute/concepts/high-availability) covers the compute-side primitives those designs use.

Vertical growth is the direct path: extend the data volume for capacity, or resize the instance flavor for CPU and memory.

## Further reading

- [Database networking and access](/docs/databases/concepts/database-networking-and-access): private addressing, security group boundaries, and administrative paths
- [Database backup and recovery](/docs/databases/concepts/database-backup-and-recovery): the recovery layers a database deployment can use
- [Volumes](/docs/block/concepts/volumes): volume lifecycle, snapshots, and consistency
- [Security groups](/docs/network/concepts/security-groups): how rules attach to instance ports
- [Deploy the self-managed PostgreSQL template with OpenTofu](/resources/deployments/deploy-self-managed-postgres-template): the PostgreSQL deployment walkthrough
- [Deploy the MySQL/MariaDB database template with OpenTofu](/resources/deployments/deploy-mysql-database-template): the MySQL/MariaDB deployment walkthrough
