Docs
Skip to content

MySQL

Grafana_

Connect Grafana to an Appwrite native MySQL database as a data source and build dashboards. Configure the MySQL data source and provision it from YAML.

4 min read

Raw

An Appwrite native MySQL database exposes a standard managed MySQL 8.4 or 8.0 engine, so Grafana connects to it through the built-in MySQL data source with no Appwrite-specific configuration. Point the data source at your database hostname, authenticate with your database credentials, and query your tables to build dashboards and alerts.

Protect dashboard credentials

Grafana can execute any SQL allowed by the data source user. Keep panel queries read-only, avoid saving write statements in dashboards, and restrict network access to trusted Grafana hosts with an IP allowlist. If your deployment has a secondary MySQL user with only SELECT privileges, use that user for Grafana.

Choose a connection target

Grafana holds its data source connections open for the lifetime of the process. Long-lived connections should use either the direct MySQL port 3306 or a connection pooler on port 6033 running in session mode.

Do not point Grafana at the transaction-mode pooler. Transaction mode hands a backend connection back to the pool after every statement, which breaks the session assumptions Grafana relies on for connection reuse and prepared statements. For a typical dashboard workload the direct MySQL port is the simplest choice. See the pooler modes page for the trade-offs.

Add the MySQL data source

In Grafana, open Connections > Data sources > Add data source and select MySQL. Fill in the connection details using the values from your native MySQL database:

FieldValue
Host URLdb-<hash>.<region>.appwrite.center:3306
Database<database>
Usernameadmin
Password<password>

Regions are fra, nyc, sfo, sgp, syd, and tor. Appwrite Cloud encrypts connections to the public hostname with TLS. Grafana's MySQL data source uses MySQL-specific TLS fields such as tlsAuthWithCACert, tlsSkipVerify, and TLS certificate values in secureJsonData.

If you use Grafana Cloud and restrict database access with an IP allowlist, add the Grafana Cloud outbound IP ranges for your stack to the database allowlist. Grafana Cloud can reach the public Appwrite database hostname directly. Private connectivity features are only needed when the database is on a private network.

Under Connection limits, keep the connection counts modest so Grafana doesn't exhaust the engine's connection budget. Max open caps total connections from this Grafana instance, Max idle caps pooled idle connections, and Max lifetime recycles connections after the given number of seconds. Select Save & test to verify connectivity.

Provision from YAML

Instead of configuring the data source by hand, you can provision it declaratively. Drop a file into Grafana's provisioning/datasources/ directory and read the password from an environment variable so it never lands in source control:

YAML
apiVersion: 1
datasources:
- name: Appwrite native MySQL
type: mysql
url: db-<hash>.<region>.appwrite.center:3306
user: admin
jsonData:
database: <database>
maxOpenConns: 5
maxIdleConns: 2
maxIdleConnsAuto: true
connMaxLifetime: 14400
secureJsonData:
password: $GRAFANA_DB_PASSWORD
editable: false

The MySQL data source uses type: mysql, keeps the database name under jsonData.database, and reads the password from secureJsonData.password. Grafana expands $GRAFANA_DB_PASSWORD from the process environment when it loads the provisioning file. Add Grafana's MySQL TLS fields if your deployment requires explicit TLS configuration. See the MySQL data source docs for every available field.

Build a panel

With the data source connected, create a dashboard and add a panel backed by it. Switch the query editor to code mode and write a read-only query against your tables. For example, to plot daily sign-ups from a grafana_users table over time:

Plain text
SELECT
CAST(DATE(created_at) AS DATETIME) AS time,
COUNT(*) AS signups
FROM grafana_users
GROUP BY CAST(DATE(created_at) AS DATETIME)
ORDER BY time;

Grafana maps the time column to the panel's time axis and signups to the value. MySQL 8.4 enables ONLY_FULL_GROUP_BY, so the selected time expression must match the grouped expression.

Was this page helpful?

Share what worked or what we should fix. Once approved, our agents automatically apply suggested updates to the docs.