As a DBA, you're expected to know what's happening inside your databases at all times.
But here's the reality — most monitoring setups are either too generic (CPU is high!) or too custom (someone's 3-year-old Grafana dashboard nobody understands).
What if there was a tool built specifically for database engineers — one that understands query performance, replication lag, vacuum bloat, and connection saturation right out of the box?
That tool is Percona Monitoring and Management (PMM).
In this post, I'll walk you through everything you need to know about PMM 3 — what it is, how it works internally, how to install it, what features it brings, and which databases it supports.
Let's get into it.
What is PMM?
PMM (Percona Monitoring and Management) is a 100% free, open-source database observability and monitoring platform built by Percona.
It is NOT a generic infrastructure monitoring tool like Nagios or Zabbix.
PMM was purpose-built for DBAs who need to answer questions like:
- Which query is consuming the most database time?
- How far behind is my replica?
- Is my autovacuum keeping up with dead tuples?
- Are connections about to hit the limit?
- Which tables are approaching transaction ID wraparound?
Generic monitoring tools can't answer these. PMM can — and it does it with zero application-side instrumentation.
Think of PMM as a pre-assembled, database-aware monitoring stack that combines Grafana + VictoriaMetrics + ClickHouse + Prometheus + AlertManager into a single deployable unit, with 20+ pre-built dashboards per database engine.
The latest version is PMM 3.8.0, released on May 28, 2026.
Architecture Overview:
PMM Server
The PMM Server is a self-contained unit — deployed as a Docker container, Podman container, Helm chart on Kubernetes, Virtual Appliance (OVA), or AWS AMI.
It contains the following internal components:
PMM Client
The PMM Client is installed on the same machine as your database server. It runs a lightweight agent process.
How They Communicate
This is the part that surprises most people:
PMM uses a single port (443) for ALL communication.
The pmm-agent on the database server opens a persistent outbound gRPC tunnel to the PMM Server. All metrics, QAN data, and control plane messages travel through this single encrypted channel.
What this means practically:
- ✅ Your database server needs NO inbound firewall rules
- ✅ The exporters listen on localhost only — they are not exposed on the network
- ✅ PMM Server cannot execute queries against your database — it only receives data
Here's the high-level data flow:
Component Summary
Prerequisites & Dependencies:
Database-Specific Prerequisites
For PostgreSQL Monitoring:
- A dedicated monitoring user (e.g., pmm_user) with SUPERUSER or appropriate privileges
- pg_stat_statements extension loaded (shared_preload_libraries)
- pg_hba.conf configured for password authentication from 127.0.0.1
For MySQL Monitoring:
- A dedicated monitoring user (e.g., pmm) with appropriate grants
- performance_schema = ON (enabled by default in MySQL 8.x)
- Grants: SELECT, PROCESS, REPLICATION CLIENT, RELOAD, BACKUP_ADMIN
Network & Firewall Requirements
PMM Server Installation (On PMM Server Instance):
apt update && apt install -y ca-certificates curl gnupg lsb-release
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.ascecho "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${VERSION_CODENAME}") stable" \
> /etc/apt/sources.list.d/docker.listapt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugindocker --version Deploy PMM Server Container
docker pull percona/pmm-server:3docker volume create pmm-datadocker run --detach --restart always \
--publish 443:8443 \
--volume pmm-data:/srv \
--name pmm-server \
percona/pmm-server:3docker exec -t pmm-server change-admin-password 'Testing123#'Verify PMM Server Health
curl -k https://localhost/v1/readyz
# Expected: {}docker exec pmm-server supervisorctl status
clickhouse RUNNING pid 69, uptime 0:01:12
grafana RUNNING pid 1016, uptime 0:01:06
nginx RUNNING pid 70, uptime 0:01:12
pmm-agent RUNNING pid 864, uptime 0:01:09
pmm-managed RUNNING pid 71, uptime 0:01:12
postgresql RUNNING pid 68, uptime 0:01:12
qan-api2 RUNNING pid 985, uptime 0:01:07
victoriametrics RUNNING pid 1061, uptime 0:01:06
vmalert RUNNING pid 931, uptime 0:01:07
vmproxy RUNNING pid 960, uptime 0:01:07PMM Client on PostgreSQL Server ( PostgreSQL instance)
Install PMM Client (Binary Tarball)
wget https://downloads.percona.com/downloads/pmm3/3.8.0/binary/tarball/pmm-client-3.8.0-x86_64.tar.gz
tar xfz pmm-client-3.8.0-x86_64.tar.gz && cd pmm-client-3.8.0
export PMM_DIR=/usr/local/percona/pmm
sudo ./install_tarballPATH=$PATH:$PMM_DIR/bin
sudo ln -s /usr/local/percona/pmm/bin/pmm-agent /usr/local/bin/pmm-agent
sudo ln -s /usr/local/percona/pmm/bin/pmm-admin /usr/local/bin/pmm-adminRegister with PMM Server
sudo pmm-agent setup --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml \
--server-address=172.31.11.183:443 \
--server-insecure-tls \
--server-username=admin \
--server-password='Testing123#'sudo pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml &
Add PostgreSQL Service
sudo -u postgres psql -c "ALTER USER pmm_user WITH PASSWORD 'Badminton23@';"
PGPASSWORD='Badminton23@' psql -h 127.0.0.1 -U pmm_user -d postgres -c "SELECT 1;"
pmm-admin add postgresql \
--username=pmm_user \
--password='Badminton23@' \
--service-name=postgres-server \
--host=127.0.0.1 \
--port=5432 \
--query-source=pgstatstatementsPostgreSQL Service added.
Service ID : f00995c3-aec6-41d0-9c0d-b50f7f27dfa0
Service name: postgres-serverPMM Client on MySQL Server ( MYSQL Instance )
Install PMM Client (Binary Tarball)
wget https://downloads.percona.com/downloads/pmm3/3.8.0/binary/tarball/pmm-client-3.8.0-x86_64.tar.gz
tar xfz pmm-client-3.8.0-x86_64.tar.gz && cd pmm-client-3.8.0
export PMM_DIR=/usr/local/percona/pmm
sudo ./install_tarball
sudo ln -s /usr/local/percona/pmm/bin/pmm-agent /usr/local/bin/pmm-agent
sudo ln -s /usr/local/percona/pmm/bin/pmm-admin /usr/local/bin/pmm-adminRegister with PMM Server
sudo pmm-agent setup --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml \
--server-address=172.31.11.183:443 \
--server-insecure-tls \
--server-username=admin \
--server-password='Testing123#'sudo pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml &
Add MySQL Service
pmm-admin add mysql \
--username=pmm \
--password='Badminton23@' \
--service-name=mysql-server \
--host=127.0.0.1 \
--port=3306 \
--query-source=perfschemaMySQL Service added.
Service ID : ada91424-6168-4063-9a1b-33c5f9414a81
Service name: mysql-server
Table statistics collection enabled (the limit is 1000, the actual table count is 337).After adding the service:
- mysqld_exporter starts on port 42002 (AGENT_STATUS_RUNNING)
- qan_mysql_perfschema_agent starts collecting query analytics
- vmagent is restarted to include the new scrape target (7 total targets)
Verification & Dashboard Access
Check Agent Status
On any client node, verify the agent is properly connected:
pmm-admin status
Access PMM Web UI
Open your browser and navigate to:
https://<PMM_SERVER_PUBLIC_IP>:443Login credentials: admin / Testing123#
Key Dashboards to Check
Verify Metrics Collection
After 2-3 minutes, you should see:
- 3 nodes in the inventory (PMM internal + PostgreSQL host + MySQL host)
- Node metrics (CPU, memory) appearing on Node dashboards
- PostgreSQL metrics on PostgreSQL Instance Summary
- MySQL metrics on MySQL Instance Summary
- Query data in QAN (Query Analytics)
Database Flavors Supported (Open Source Edition)
Final Thoughts
- Zero application-side instrumentation — just point it at your database
- Query Analytics (QAN) that actually tells you which queries are hurting performance
- Pre-built dashboards that a DBA can use on day one
- Single port (443) outbound — no complex firewall rules
- Works across MySQL, PostgreSQL, and MongoDB in one unified view
Comments
Post a Comment