Skip to main content

Percona Monitoring and Management (PMM V3)

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 uses a client-server architecture. The PMM Server collects, stores, and visualizes metrics from PMM Clients installed on database hosts. Communication happens over HTTPS (port 443) using gRPC streams.

This is the actual architecture I set up for my lab environment — PMM 3 Server running as a Docker container on an AWS EC2 instance (Ubuntu 26.04 LTS), monitoring both a PostgreSQL 18.4 server and a MySQL 8.4.9 server within the same AWS VPC (ap-south-1).

All communication flows over a single gRPC/HTTPS port 443 — no inbound ports needed on the database servers.




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:

ComponentRole
pmm-agentProcess supervisor — manages all exporters, opens gRPC tunnel to PMM Server
node_exporterOS-level metrics — CPU, RAM, disk I/O, network, filesystem
postgres_exporter / mysqld_exporter / mongodb_exporterDatabase-specific metrics collection via system catalog queries
QAN AgentReads pg_stat_statements / Performance Schema / MongoDB profiler and pushes query analytics to the server

PMM Client

The PMM Client is installed on the same machine as your database server. It runs a lightweight agent process.

ComponentRole
pmm-agentProcess supervisor — manages all exporters, opens gRPC tunnel to PMM Server
node_exporterOS-level metrics — CPU, RAM, disk I/O, network, filesystem
postgres_exporter / mysqld_exporter / mongodb_exporterDatabase-specific metrics collection via system catalog queries
QAN AgentReads pg_stat_statements / Performance Schema / MongoDB profiler and pushes query analytics to the server

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

ComponentRoleVersion
PMM ServerCentralized monitoring hub (Grafana, VictoriaMetrics, ClickHouse, QAN)3.8.0
PMM Client (pmm-agent)Agent running on each monitored host, manages exporters3.8.0
node_exporterCollects OS/hardware metrics (CPU, memory, disk, network)1.8.2
postgres_exporterCollects PostgreSQL metrics and pg_stat_statementsBundled
mysqld_exporterCollects MySQL metrics and performance_schema dataBundled
vmagentScrapes local exporters and pushes to PMM Server's VictoriaMetricsBundled

Prerequisites & Dependencies:

PMM server Dependencies

DependencyPurposeVersion Used
Docker EngineContainer runtime for PMM Server29.5.3
containerd.ioContainer runtime (Docker dependency)2.2.4
docker-ce-cliDocker command-line interface29.5.3
docker-compose-pluginDocker Compose (optional)5.1.4
ca-certificatesSSL/TLS certificate verificationSystem
curlDownloading Docker GPG key8.18.0
gnupgGPG key management for repos2.4.8

Hardware Requirements (PMM Server):

Minimum: 2 vCPUs, 4 GB RAM, 20 GB disk
Recommended: 4+ vCPUs, 8+ GB RAM, 100+ GB disk (depends on number of monitored nodes)

PMM Client Dependencies :

DependencyPurposeNotes
wget or curlDownload PMM Client tarballPre-installed on Ubuntu
tarExtract the tarballPre-installed on Ubuntu
glibc (libc6)C library for binariesPre-installed on Ubuntu
Network access to PMM Server:443Agent-Server communicationSecurity Group must allow

Key Point: PMM Client 3.x is installed from a binary tarball — no package manager required. This makes it compatible with any Linux distribution without needing a specific repo.

Version Compatibility: PMM Client 3.x is required for PMM Server 3.x. The older pmm2-client package is NOT compatible with PMM Server 3 due to breaking API changes (endpoint changed from /v1/management/Node/Register to /v1/management/nodes).

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

PortDirectionProtocolPurpose
443Client → ServerHTTPS/gRPCAgent communication & UI access
8443Internal (Docker)HTTPSPMM Server internal port (mapped to 443)
42000-42009Localhost onlyHTTPLocal exporter ports (node, postgres, mysql, vmagent)
7777Localhost onlyHTTPpmm-agent local API server

PMM Server Installation (On PMM Server Instance):

Install Docker Engine
1. Install prerequisites and add Docker's GPG key:
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.asc
2. Add Docker repository:
echo "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.list
3. Install Docker packages:
apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
4. Verify Docker installation:
docker --version 

Deploy PMM Server Container

Pull the PMM Server 3 image:
docker pull percona/pmm-server:3
Create a Docker volume for persistent data:
docker volume create pmm-data
Run the PMM Server container:
docker run --detach --restart always \
  --publish 443:8443 \
  --volume pmm-data:/srv \
  --name pmm-server \
  percona/pmm-server:3

Port Mapping Note: PMM Server 3 uses internal port 8443 (not 443 as in PMM 2). The --publish 443:8443 maps external port 443 to the container's 8443.

Wait ~60 seconds for services to start, then set the admin password:
docker exec -t pmm-server change-admin-password 'Testing123#'

Verify PMM Server Health

Check the readiness endpoint:
curl -k https://localhost/v1/readyz
# Expected: {}
Verify all internal services are running:
docker exec pmm-server supervisorctl status

Expected output (all RUNNING):
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:07


PMM Client on PostgreSQL Server ( PostgreSQL instance)

 Install PMM Client (Binary Tarball)

Download the PMM Client 3.8.0 tarball:
wget https://downloads.percona.com/downloads/pmm3/3.8.0/binary/tarball/pmm-client-3.8.0-x86_64.tar.gz
Extract and install:
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
Add to PATH and create symlinks:
PATH=$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-admin

Register with PMM Server

Run the agent setup to register 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#'
Expected: "Registered. Configuration file /usr/local/percona/pmm/config/pmm-agent.yaml updated."

Start the pmm-agent in the background:
sudo pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml &
Production Tip: For production, create a systemd service file for pmm-agent so it starts automatically on boot. See the Troubleshooting section for an example.

Add PostgreSQL Service

Ensure the PostgreSQL monitoring user exists with the correct password:

sudo -u postgres psql -c "ALTER USER pmm_user WITH PASSWORD 'Badminton23@';"
Verify password authentication works via TCP:

PGPASSWORD='Badminton23@' psql -h 127.0.0.1 -U pmm_user -d postgres -c "SELECT 1;"
Add the PostgreSQL service to PMM:

pmm-admin add postgresql \
  --username=pmm_user \
  --password='Badminton23@' \
  --service-name=postgres-server \
  --host=127.0.0.1 \
  --port=5432 \
  --query-source=pgstatstatements

Expected output:
PostgreSQL Service added.
Service ID  : f00995c3-aec6-41d0-9c0d-b50f7f27dfa0
Service name: postgres-server
After adding the service, the agent automatically starts postgres_exporter (port 42002) and reconfigures vmagent to scrape it.

PMM Client on MySQL Server ( MYSQL Instance )
Install PMM Client (Binary Tarball)

Download, extract, and install (same steps as PostgreSQL):
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-admin

Register with PMM Server

Register the agent:
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#'
Start the agent:
sudo pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml &

Add MySQL Service

Add the MySQL service with performance_schema as query source:
pmm-admin add mysql \
  --username=pmm \
  --password='Badminton23@' \
  --service-name=mysql-server \
  --host=127.0.0.1 \
  --port=3306 \
  --query-source=perfschema
Expected output:
MySQL 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>:443

Login credentials: admin / Testing123#

Key Dashboards to Check

DashboardPurpose
Home DashboardOverview of all monitored services
Node SummaryOS-level metrics (CPU, Memory, Disk, Network)
PostgreSQL Instance SummaryPostgreSQL performance metrics
MySQL Instance SummaryMySQL performance metrics
Query Analytics (QAN)Slow query analysis from pg_stat_statements / performance_schema

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)

CategoryDatabase / ServiceWhat PMM Monitors
MySQL familyMySQL Community 8.0, 8.4 LTSQAN (slow log + perf schema), InnoDB, replication, connections
MySQL EnterpriseSame as above
Percona Server for MySQLEnhanced QAN with slow log sampling
Percona XtraDB Cluster (PXC)Galera replication, cluster state, PXC-specific dashboards
MariaDBMetrics and QAN
PostgreSQL familyPostgreSQL 13–18QAN via pg_stat_statements or pg_stat_monitor, vacuum, replication, locks, WAL, checkpoints
Percona Distribution for PostgreSQLSame + Advisor checks
MongoDB familyMongoDB Community 6, 7, 8QAN, replica sets, sharding, WiredTiger cache, oplog
Percona Server for MongoDBSame + enhanced checks
MongoDB EnterpriseSame
In-memory / CacheValkey (formerly Redis fork)Key metrics, memory, connections
RedisSame
ProxiesProxySQLConnection pool, query routing stats, backend health
HAProxyLoad balancer metrics, backend status
CloudAWS RDS / Aurora (MySQL & PG)RDS-specific metrics via CloudWatch exporter
Azure DatabaseAzure monitor integration
Google Cloud SQLGCP-specific integration
Linux OSAny Linux hostCPU, RAM, disk I/O, network, filesystem
External / CustomAny Prometheus-compatible exporterPlug in any custom exporter


The following screenshots provide a visual overview of the PMM dashboards and monitoring capabilities. They demonstrate how PMM delivers real-time insights into database performance, system health, query analytics, replication status, and infrastructure metrics through a unified interface.






Final Thoughts

PMM 3 is one of the most underrated tools in the DBA toolbox. It's free, it's open-source, and it gives you production-grade observability without writing a single line of monitoring code.

What makes it stand out:
  • 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
If you're running databases in production without something like PMM, you're flying blind. Set it up once, and you'll wonder how you ever managed without it.

Have questions or ran into issues? Drop a comment below — happy to help troubleshoot.


Comments

Popular posts from this blog

🚀 Automating Oracle Database Patching with Ansible: A Complete Guide

Oracle database patching has long been the bane of DBAs everywhere. It's a critical task that requires precision, expertise, and often results in extended maintenance windows. What if I told you that you could automate this entire process, reducing both risk and downtime while ensuring consistency across your Oracle estate? 💡 In this comprehensive guide, I'll walk you through a production-ready Ansible playbook that completely automates Oracle patch application using OPatch. Whether you're managing a single Oracle instance or hundreds of databases across your enterprise, this solution will transform your patch management strategy! 🎯 🔥 The Challenge: Why Oracle Patching is Complex Before diving into the solution, let's understand why Oracle patching is so challenging: 🔗 Multiple dependencies : OPatch versions, Oracle Home configurations, running processes ⚠️ Risk of corruption : Incorrect patch application can render databases unusable ⏰ Downtime requirements : Da...

🚀 DB BOT: Real-Time Oracle & GoldenGate Monitoring in Slack

In today's fast-paced DevOps environment, quick access to database metrics is essential. This blog will walk you through creating a Slack bot that provides real-time monitoring of Oracle databases and Golden Gate replication. With simple slash commands, your team can check tablespace usage, Flash Recovery Area status, and Golden Gate replication health directly in Slack. Project Overview Our "DB Bot" offers these key capabilities: Monitor tablespace usage across multiple Oracle databases Check Flash Recovery Area (FRA) status on multiple databases View GoldenGate process status across different servers List GoldenGate credential stores Monitor replication lag in GoldenGate Prerequisites Node.js v14+ Python 3.6+ Oracle client libraries (instantclient_21_19) Access to Oracle databases and GoldenGate servers A Slack workspace with permissions to add apps   Project Structure oracle-slack-bot...

Oracle Golden Gate Bi-directional Replication Implementation Guide

Oracle GoldenGate (OGG) is a comprehensive software package for real-time data integration and replication in heterogeneous IT environments. Bi-directional replication enables organizations to maintain synchronized data across multiple data centers, providing high availability, disaster recovery, and load distribution capabilities. This detailed guide provides step-by-step instructions for implementing Oracle GoldenGate bi-directional replication between two Oracle databases. Architecture Overview In this setup, we'll configure: TestDC1 : Primary data center with TestDB1 TestDC2 : Secondary data center with TestDB2 Bi-directional sync : Changes flow in both directions with conflict resolution Step 1: Software Installation ⚠️ SERVER EXECUTION: Perform these steps on BOTH TestDC1 and TestDC2 servers Step 1.1: Download and Prepare Software First, create the necessary directory structure and prepare for installation: # Create directory for the software mkdir /data01/ogg_setup cd /d...