---
title: Add a PostgreSQL or MySQL database to your project
description: Create a dedicated PostgreSQL or MySQL database, connect it to a project so its own account owns the tables, and create tables from Claude Code or Codex.
url: https://agentlab.cresclab.com/docs/en/deploy/databases
language: en
updated: 2026-10-28
---

# Add a PostgreSQL or MySQL database to your project

Create a dedicated PostgreSQL or MySQL database, connect it to a project so its own account owns the tables, and create tables from Claude Code or Codex.

## The quickest way: let the deploy create it

If your code reads a database connection variable such as `DATABASE_URL`, `POSTGRES_URL`, `MYSQL_URL` or `DB_HOST` and `DB_PASSWORD`, and the project has no value for it yet, deploying from an AI tool or uploading in the console creates a size S database and connects it before the build starts. It is PostgreSQL, or MySQL when the code reads `MYSQL_` names. Nothing else to do: ask your AI tool to deploy.

```prompt
Deploy this folder to Agent Lab. It uses PostgreSQL through DATABASE_URL.
```

When this happens, when it doesn't, and what the AI tool sees while it waits: [Databases and caches the code needs](https://agentlab.cresclab.com/docs/en/deploy/mcp-tools.md#auto-provision). The rest of this page is for creating and managing a database yourself.

## What you get

Each database is its own dedicated Google Cloud SQL instance, with its own public address. Nothing is shared with other organizations.

| Item    | Choices                                                                                                                                                      |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Engine  | PostgreSQL 18 (the default), 17 or 16; MySQL 8.4 or 9.7 where the console lists them. Fixed for the database's life.                                         |
| Size    | S: shared core, 0.6 GB memory, for development and testing only, no SLA. M: 1 vCPU, 3.75 GB. L: 2 vCPU, 8 GB. XL: 4 vCPU, 16 GB.                             |
| Region  | Taiwan (`asia-east1`), Japan (`asia-northeast1`), United States (`us-central1`) or Europe (`europe-west1`). Fixed for the database's life.                   |
| Storage | At least 10 GB. It can grow, automatically if you turn that on, but never shrink.                                                                            |
| Backups | Taken automatically. Point-in-time recovery for the last 7 days is a Business add-on ([below](https://agentlab.cresclab.com/docs/en/deploy/databases.md#pitr)). |

Inside one instance you can keep several databases, for example one per project. Each database belongs to one [environment](https://agentlab.cresclab.com/docs/en/deploy/glossary.md), and a project connects only to databases in its own environment.

## What your plan includes

| Plan     | Databases   | Sizes | Point-in-time recovery |
| -------- | ----------- | ----- | ---------------------- |
| Free     | 1           | S     | No                     |
| Pro      | 2           | S, M  | No                     |
| Team     | 10          | S–XL  | No                     |
| Business | By contract | S–XL  | Add-on                 |

- **Free:** the database isn't charged; it counts toward the free quota. It needs a card on file first (nothing is charged), and it stops by itself after 7 days without use. Start it again from its page.
- **Paid plans:** billing starts when the database is created. A stopped database pays only for its storage. Prices are on the [pricing page](https://agentlab.cresclab.com/en/deploy#pricing).
- Only organization owners and admins can create a database, because it is billed.

## Create a database

**Console**

1. Open **Databases** and select **Create database**.
2. Choose the **Database type** and **Version**, a **Name** (up to 63 characters), the **Machine size**, the **Region** closest to the services that will connect, and the storage.
3. Under **Encryption**, keep **Allow only SSL connections** unless you have a reason not to ([connection security](https://agentlab.cresclab.com/docs/en/deploy/databases.md#security)).
4. Under **Connections**, add the IPv4 addresses that will connect, or turn on **Allow services running on Agent Lab**.
5. Select **Create database**.

**AI tool**

```prompt
Create an Agent Lab PostgreSQL database named orders, size S, in Taiwan, that my Agent Lab projects can connect to.
```

The assistant calls `databases_create`, shows you a preview, and creates it only after you agree, because billing starts at once. See [MCP tools › Databases](https://agentlab.cresclab.com/docs/en/deploy/mcp-tools.md#databases).

Creating a database usually takes 10–15 minutes. MySQL on size S can take longer.

## Connect a project

Connecting gives the project its own database account, with a strong password Agent Lab generates, and writes the connection into the project's secrets. Nobody sees the password, not you and not the AI tool.

**AI tool**

```prompt
Connect my orders-api project to the orders database. Read the code to see which variables it uses.
```

The assistant reads which variables the code expects and calls `databases_connect_app` with each name and the part of the connection it carries:

```json
{
  "database": "orders",
  "site": "<project id from sites_list>",
  "variables": { "DATABASE_URL": "url" }
}
```

Other parts are `jdbcUrl`, `host`, `port`, `hostPort`, `database`, `user`, `password`, `sslmode` and `ca` (the server CA). A preview lists the variables it would write and any it would replace; after you agree, it creates the account and restarts the project.

**Console**

1. On the database's **Users and databases** tab, create a database and a user for the project. Choose **Owner: full control of the database** if the project creates its own tables. Copy the password; it is shown once.
2. On the database's **Overview** tab, copy the connection string and fill in the user, password and database.
3. Add it to the project as a secret, such as `DATABASE_URL`, and restart the project. See [Project settings](https://agentlab.cresclab.com/docs/en/deploy/app-settings.md#secrets).

What connecting does:

- **The project's account owns its own database.** It can create and change tables, so migrations that an ORM runs at start-up (Prisma, Drizzle, Django, Rails, Laravel, TypeORM and the like) work. It reaches no other database on the instance, and it can't create accounts or databases. Ask for `write` (read and write data, no schema changes) or `read` if the project needs less.
- **A database is created inside the instance** when the project has none yet. It is named after the project's address label, with hyphens turned into underscores, unless you name it: a lowercase letter first, then lowercase letters, digits and underscores, at most 50 characters on PostgreSQL and 64 on MySQL.
- **The allowlist is opened to Agent Lab** if it wasn't: **Allow services running on Agent Lab** is turned on.
- **Encryption:** the `url` part uses `sslmode=require` on PostgreSQL. On MySQL it carries no TLS setting, because each driver spells it differently: turn TLS on in your driver.
- A database that requires client certificates can't be connected this way yet. Connect the project by hand, or change its encryption to **Allow only SSL connections**.

To disconnect, `databases_disconnect_app` removes the account and the variables it wrote; the data stays. `databases_rotate_app_password` gives the project a new password and restarts it.

## Create tables and query data from an AI tool

From Claude Code, Codex or another MCP client connected to Agent Lab, you don't need a database password or a SQL client:

```prompt
In the orders database, create a notes table with an id, a body and a created_at timestamp, then show me the tables.
```

- `list_tables` shows the tables, `apply_migration` runs a named migration (a transaction on PostgreSQL; statement by statement on MySQL), and `execute_sql` runs one query. The assistant shows you the SQL before it runs.
- Every migration is recorded with its name and SQL, in the database's own `agentlab_data_control.migrations` table.
- Owners, admins, the database's creator and its database admins can already write. Other members need **Reader** or **Writer** access, given on the database's **Data access** section or with `databases_grant`.

Arguments, limits and examples: [MCP tools › Database data tools](https://agentlab.cresclab.com/docs/en/deploy/mcp-tools.md#database-data).

## Connect from your computer or another host

Add your IPv4 address under **Authorized networks** on the database's **Settings** tab, then connect to the address on its **Overview** tab with a user from **Users and databases**. Download `server-ca.pem` from the **Certificates** tab.

```sh
psql "host=<address> port=5432 dbname=orders user=<user> sslmode=verify-ca sslrootcert=server-ca.pem"
```

```sh
mysql --host=<address> --port=3306 --user=<user> --password \
  --ssl-mode=VERIFY_CA --ssl-ca=server-ca.pem orders
```

Use `verify-ca` (PostgreSQL) or `VERIFY_CA` (MySQL): `verify-full` and `VERIFY_IDENTITY` don't work with an IP address. MySQL 9.7 accepts only `caching_sha2_password`, so use the MySQL 8.0 client or later, Connector/J 8.0 or later, or PHP 7.4 or later. The **Overview** tab has examples for Node.js, Python, Go, Java and PHP.

## Connection security

| Setting                                 | What it does                                                                                                                |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **Authorized networks**                 | Up to 20 public IPv4 addresses or CIDR ranges that may connect. Nothing else can.                                           |
| **Allow services running on Agent Lab** | Adds Agent Lab's outbound address. It is shared by every organization's services, so the password is what keeps others out. |
| **Allow all IPs (0.0.0.0/0)**           | Anyone on the internet can try to connect.                                                                                  |
| **Allow only SSL connections**          | The default and the recommendation: every connection uses TLS.                                                              |
| **Require trusted client certificates** | Every connection also presents a client certificate issued on the **Certificates** tab, besides the password.               |
| **Allow unencrypted network traffic**   | Clients may connect without TLS. Not recommended.                                                                           |

Client certificates are issued on the **Certificates** tab with **Issue certificate**. The private key is shown once: download `client-key.pem` before you close the dialog. Issue the new certificate before revoking the old one, so clients can switch without downtime. On MySQL, revoking a certificate ends every current connection; clients with a valid certificate reconnect.

With certificates, add them to the connection:

```sh
psql "host=<address> port=5432 dbname=orders user=<user> sslmode=verify-ca sslrootcert=server-ca.pem sslcert=client-cert.pem sslkey=client-key.pem"
```

A MySQL database that requires a certificate answers `Access denied` without one, exactly as for a wrong password: check the certificate first.

The **Connections** section lists who connected in the last 30 days, from which address, and why a failed sign-in was refused. `databases_connections` answers the same.

## Move an existing database in

Make a dump with `pg_dump` or `mysqldump`, then use **Import data** on the database's row, or ask the AI tool, which uses `databases_import`. Agent Lab checks every statement before anything runs and lists what it refuses, with line numbers. The dump commands and what is skipped: [MCP tools › Moving a database in](https://agentlab.cresclab.com/docs/en/deploy/mcp-tools.md#import).

## Stop, start and delete

- **Stop** keeps the data and the address; every connection drops. On a paid plan the storage is still billed. **Start** brings it back at the same address within a few minutes.
- **Delete database** asks you to type its name. Choose **Take a final backup before deleting** to keep a last backup; a stopped database is started first for it.
- From an AI tool: `databases_stop` and `databases_start`.

## Restore to a point in time

On the Business plan, turn on **Point-in-time recovery (PITR)** in the database's **Settings**. You can then use **Restore to a point in time** to pick any moment in the last 7 days after it was turned on.

- A restore creates a **new** database with the data as of that moment. The original isn't changed. The new database counts toward your plan and is billed on its own, and starts with point-in-time recovery off.
- On MySQL, turning point-in-time recovery on or off restarts the database: connections drop for several minutes, up to about 20 on size S.
- Only owners and admins can start a restore.
