Skip to content

MySQL

Tested with: MySQL 8.4.6 on Databasezy (Percona Operator for MySQL) · zb CLI 0.1

MySQL is the relational engine behind a large share of web applications and frameworks. Databasezy runs it on the Percona Operator for MySQL with TLS on every connection.

Instances start with one primary. On paid plans you can add a standby for high availability (--ha) and read replicas (--replicas). 8.4 is the default for new instances; choose 8.0 only when an application needs it.

MySQL at a glance, from the engine catalogue
Status Available
CategoryRelational
Versions8.4, 8.0 (newest is the default)
Protocol and port MySQL wire protocol on 3306
RuntimeOperator-backed (Percona Operator for MySQL)
Backupsmysqldump (logical dump)
Point-in-time recoveryNo
PauseScale to zero
Free planYes (size f0)
FeaturesRead replicas, High availability (standby)
LicenceGPL-2.0
  1. Open the portal and choose New instance.
  2. Pick MySQL and a version (8.4, 8.0).
  3. Choose a size and region. On the Free plan the size is f0. Secure placement is listed only after your organization has signed the BAA.
  4. Check the hourly price and monthly estimate, then confirm. The Connect tab fills in when the instance is ready.

Every snippet uses ssl-mode=VERIFY_IDENTITY or the driver’s equivalent, so both the certificate chain and the host name are checked.

MySQL listens on port 3306 (MySQL wire protocol). Versions: 8.4, 8.0. Replace the example host with the one on your instance's Connect tab; credentials are shown once at creation.

Connection URI
mysql://app:<password>@mysql-7f3k.us-east.databasezy.com:3306/app?ssl-mode=VERIFY_IDENTITY&ssl-ca=databasezy-ca.pem
db.js
import { readFileSync } from "node:fs";
import mysql from "mysql2/promise";
export const pool = mysql.createPool({
host: "mysql-7f3k.us-east.databasezy.com",
port: 3306,
user: "app",
password: process.env.ZB_PASSWORD,
database: "app",
ssl: {
ca: readFileSync("databasezy-ca.pem", "utf8"),
rejectUnauthorized: true, // verify chain and hostname
},
connectionLimit: 10,
});
const [rows] = await pool.query("select version() as v");
console.log(rows[0].v);

Tested with: MySQL 8.4 · mysql2 3.11

The MySQL connection guide covers TLS, pooling and the allow-list in more depth. Framework guides: Laravel, Rails, Django, Prisma, Drizzle, Spring, SQLAlchemy.

See Connecting to Databasezy for host names, the CA bundle and the allow-list, which work the same for every engine.

You can bring an existing MySQL database in from these sources. Each links to a step-by-step guide.

Where you can migrate a MySQL database from, how, and whether continuous sync is available
Source How Continuous sync Guide status
Amazon RDS and Aurora Connection string Yes Coming soon · phase 2
Railway Connection string Yes Coming soon · phase 2
Aiven Connection string Yes Coming soon · phase 2
DigitalOcean Managed Databases Connection string Yes Coming soon · phase 2
Google Cloud SQL Connection string Yes Coming soon · phase 3
Azure Database Connection string Yes Coming soon · phase 3
PlanetScale Connection string No Available
Self-hosted server Connection string, Local tools (zb migrate --from local) Yes Available
Local files and dumps File upload, Local tools (zb migrate --from local) No Available
Docker container Local tools (zb migrate --from local) No Available
Another Databasezy instance Instance to instance Yes Coming soon · phase 2

MySQL sources can use continuous sync through GTID-based binlog replication when the source allows an outside replica (PlanetScale does not). Moving to MariaDB later is covered in engine conversions.

How migrations work explains preflight, verification and cutover.

Backups are consistent logical dumps (mysqldump --single-transaction) taken on your plan’s schedule, and a backup restores into a new instance. The binary log is not archived yet, so point-in-time recovery is not offered for MySQL; restore to the most recent backup instead.

MySQL backups use mysqldump (logical dump). They run inside the instance's namespace, stream straight to the cell's object storage and are checksummed on upload. How often they run and how long they are kept follows your plan's backup policy. A backup is always taken before a resize or a version upgrade.

Point-in-time recovery is not available for MySQL. A restore returns the data as of a scheduled or manual backup. Restores create a new instance by default and leave the original untouched; an in-place restore asks you to type the instance name and takes a pre-change backup first.

shell
zb backups create mysql-demo --label before-release # manual snapshot
zb backups list mysql-demo
zb backups restore mysql-demo <backup-id> --name mysql-demo-restore

MySQL can scale to zero. A paused instance has no running pods and bills no compute; its storage and backups are kept and billed as usual. Connections are refused until you resume it. On the Free plan an instance pauses by itself after 15 minutes without connections and wakes on the next one; the gateway holds that connection for up to 30 seconds while it starts.

shell
zb instances pause mysql-demo
zb instances resume mysql-demo

See Pause and resume for schedules, wake times and billing while paused.

MySQL runs on every size, including the Free plan's f0. The size sets the CPU, memory, storage ceiling and connection limit; the gateway refuses connections over the limit with a protocol error. Storage grows in steps up to the ceiling, and you can resize at any time.

Sizes available for MySQL: vCPU, memory, storage ceiling, connection limit and monthly price
Size vCPU Memory Max storage Max connections ≈ $ / month
f0 0.063 512 MiB 1 GB 20 Free
s0 0.25 1 GiB 20 GB 60 $10
s1 0.5 2 GiB 50 GB 100 $15
s2 1 4 GiB 200 GB 200 $60
m2 2 8 GiB 500 GB 400 $110
m4 4 16 GiB 1 TB 800 $210
l8 8 32 GiB 4 TB 1,500 $410
l16 16 64 GiB 8 TB 3,000 $960
xl32 32 128 GiB 16 TB 5,000 $1,870

Full details, including hourly prices and burst CPU, are in the size catalogue; plan quotas are in limits and quotas.

The app user has every privilege on the app database and none outside it, so it cannot create other databases or users. After a credential rotation the previous password keeps working for 10 minutes, then MySQL discards it. Clients must negotiate TLS; use VERIFY_IDENTITY rather than REQUIRED, which encrypts without checking the server.

  • TLS on every connection. TLS 1.2 is the minimum and TLS 1.3 is preferred; plaintext is never offered. Verify the server, not just the encryption: use ssl-mode=VERIFY_IDENTITY. See TLS and the CA bundle.
  • IP allow-list. The gateway checks the client address before authentication, on every plan. Manage it under Network → Allow-list in the portal or with PUT /v1/orgs/{org}/instances/{id}/network.
  • Credentials. Generated inside the cell, shown once, never stored by the control plane. Rotate them with an overlap window so nothing breaks.
  • Secure hosting. Secure placement (HIPAA-ready) is a per-instance option once your organization has signed the BAA: dedicated nodes, customer-managed keys and immutable backups. See Secure hosting and the BAA.
  • Staff access. Databasezy staff cannot read your data without a grant you issue. See data confidentiality.

8.4 for anything new. 8.0 is past its upstream end of life and deprecated: new 8.0 instances are refused from 2027-01-05, with notices 90, 30 and 7 days ahead. Moving from 8.0 to 8.4 is not an in-place upgrade (8.4 rewrites the data dictionary, which 8.0 cannot read back): create an 8.4 instance and migrate into it, or restore an 8.0 backup into a new 8.4 instance, then switch your application over.

My client fails with a TLS error. What changed?

Section titled “My client fails with a TLS error. What changed?”

Databasezy never accepts plaintext MySQL connections. Set --ssl-mode=VERIFY_IDENTITY (or your driver’s equivalent) and pass the CA bundle from the Connect tab if your driver does not use the system trust store. The mysql command-line client (8.x) also needs --tls-sni-servername=<host>: the gateway routes each connection by the TLS server name, which that client does not send by default (drivers and the mariadb client do).

Can I migrate from PlanetScale with zero downtime?

Section titled “Can I migrate from PlanetScale with zero downtime?”

No. Vitess does not let an outside replica read the binlog, so a PlanetScale migration is copy only with a write freeze. See From PlanetScale.