Integrate MinIO with Prometheus monitoring for performance metrics and observability

Intermediate 35 min Apr 15, 2026 314 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up comprehensive monitoring for your MinIO object storage cluster with Prometheus metrics collection, Grafana visualization dashboards, and automated alerting rules for production environments.

Prerequisites

  • MinIO server installed and running
  • Prometheus server configured
  • Grafana dashboard access
  • Administrative privileges

What this solves

MinIO object storage requires comprehensive monitoring to ensure optimal performance, track storage usage, and maintain service reliability in production environments. This tutorial shows you how to configure MinIO's built-in Prometheus metrics endpoint, set up automated metrics collection with Prometheus, create detailed Grafana dashboards for visualization, and implement alerting rules for proactive monitoring.

Prerequisites

Before starting this tutorial, you need a working MinIO installation with administrative access. You'll also need Prometheus and Grafana installed on your system. If you haven't set these up yet, refer to our MinIO clustering guide and Prometheus monitoring stack tutorial.

Step-by-step configuration

Enable MinIO Prometheus metrics endpoint

First, configure MinIO to expose metrics on its dedicated endpoint for Prometheus collection.

sudo systemctl stop minio
sudo mkdir -p /etc/minio

Configure MinIO environment variables

Set the required environment variables to enable Prometheus metrics collection and specify the metrics path.

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=your-secure-password-here
MINIO_VOLUMES=/data/minio
MINIO_OPTS="--console-address :9001"
MINIO_PROMETHEUS_AUTH_TYPE=public
MINIO_PROMETHEUS_URL=http://localhost:9000
MINIO_SERVER_URL=http://localhost:9000

Create MinIO systemd service configuration

Update the MinIO systemd service to use the environment configuration and enable metrics.

[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio

[Service]
WorkingDirectory=/usr/local/
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
TasksMax=infinity
TimeoutStopSec=infinity
SendSIGKILL=no

[Install]
WantedBy=multi-user.target

Start MinIO with metrics enabled

Reload systemd configuration and restart MinIO to enable the Prometheus metrics endpoint.

sudo systemctl daemon-reload
sudo systemctl start minio
sudo systemctl enable minio
sudo systemctl status minio

Verify MinIO metrics endpoint

Test that MinIO is exposing metrics on the Prometheus endpoint before configuring Prometheus collection.

curl -s http://localhost:9000/minio/v2/metrics/cluster | head -20

Configure Prometheus scraping for MinIO

Add MinIO as a scraping target in your Prometheus configuration to collect metrics automatically.

global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "minio_alerts.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'minio-job'
    metrics_path: /minio/v2/metrics/cluster
    scheme: http
    static_configs:
      - targets: ['localhost:9000']
    scrape_interval: 15s
    scrape_timeout: 10s

Create MinIO alerting rules

Define Prometheus alerting rules for common MinIO issues like high disk usage, API errors, and service availability.

groups:
  - name: minio-alerts
    rules:
      - alert: MinIONodeDown
        expr: up{job="minio-job"} == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "MinIO node is down"
          description: "MinIO node {{ $labels.instance }} has been down for more than 5 minutes."

      - alert: MinIOHighDiskUsage
        expr: (minio_cluster_capacity_usable_free_bytes / minio_cluster_capacity_usable_total_bytes) * 100 < 15
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "MinIO disk usage is high"
          description: "MinIO cluster has less than 15% free disk space remaining."

      - alert: MinIOHighAPIErrorRate
        expr: rate(minio_s3_requests_errors_total[5m]) > 0.1
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "MinIO API error rate is high"
          description: "MinIO API error rate is above 10% for the last 5 minutes."

      - alert: MinIOHighMemoryUsage
        expr: (minio_cluster_usage_total_bytes / minio_cluster_capacity_usable_total_bytes) * 100 > 85
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: "MinIO memory usage is high"
          description: "MinIO cluster memory usage is above 85% for 15 minutes."

      - alert: MinIOSlowRequests
        expr: histogram_quantile(0.95, rate(minio_s3_requests_duration_seconds_bucket[5m])) > 1
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "MinIO requests are slow"
          description: "95th percentile of MinIO request duration is above 1 second."

Restart Prometheus with new configuration

Reload Prometheus configuration to start collecting MinIO metrics and enable alerting rules.

sudo systemctl restart prometheus
sudo systemctl status prometheus

Configure Grafana data source

Add Prometheus as a data source in Grafana if not already configured for MinIO metrics visualization.

curl -X POST \
  http://admin:admin@localhost:3000/api/datasources \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Prometheus",
    "type": "prometheus",
    "url": "http://localhost:9090",
    "access": "proxy",
    "isDefault": true
  }'

Create MinIO Grafana dashboard

Import a comprehensive MinIO dashboard configuration for monitoring cluster performance, storage usage, and API metrics.

{
  "dashboard": {
    "id": null,
    "title": "MinIO Cluster Monitoring",
    "tags": ["minio", "storage"],
    "timezone": "browser",
    "panels": [
      {
        "id": 1,
        "title": "MinIO Cluster Status",
        "type": "stat",
        "targets": [
          {
            "expr": "up{job=\"minio-job\"}",
            "legendFormat": "{{ instance }}"
          }
        ],
        "gridPos": {"h": 8, "w": 12, "x": 0, "y": 0}
      },
      {
        "id": 2,
        "title": "Storage Usage",
        "type": "graph",
        "targets": [
          {
            "expr": "minio_cluster_usage_total_bytes",
            "legendFormat": "Used Storage"
          },
          {
            "expr": "minio_cluster_capacity_usable_total_bytes",
            "legendFormat": "Total Capacity"
          }
        ],
        "gridPos": {"h": 8, "w": 12, "x": 12, "y": 0}
      },
      {
        "id": 3,
        "title": "API Request Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(minio_s3_requests_total[5m])",
            "legendFormat": "{{ method }}"
          }
        ],
        "gridPos": {"h": 8, "w": 24, "x": 0, "y": 8}
      },
      {
        "id": 4,
        "title": "Error Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(minio_s3_requests_errors_total[5m])",
            "legendFormat": "Errors per second"
          }
        ],
        "gridPos": {"h": 8, "w": 12, "x": 0, "y": 16}
      },
      {
        "id": 5,
        "title": "Response Time",
        "type": "graph",
        "targets": [
          {
            "expr": "histogram_quantile(0.95, rate(minio_s3_requests_duration_seconds_bucket[5m]))",
            "legendFormat": "95th percentile"
          },
          {
            "expr": "histogram_quantile(0.50, rate(minio_s3_requests_duration_seconds_bucket[5m]))",
            "legendFormat": "50th percentile"
          }
        ],
        "gridPos": {"h": 8, "w": 12, "x": 12, "y": 16}
      }
    ],
    "refresh": "30s",
    "time": {"from": "now-1h", "to": "now"}
  }
}

Import the dashboard to Grafana

Load the MinIO dashboard configuration into Grafana for immediate visualization of metrics.

curl -X POST \
  http://admin:admin@localhost:3000/api/dashboards/db \
  -H 'Content-Type: application/json' \
  -d @/tmp/minio-dashboard.json

Configure alerting notifications

Set up notification channels in Grafana to receive alerts when MinIO issues are detected.

curl -X POST \
  http://admin:admin@localhost:3000/api/alert-notifications \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "minio-alerts",
    "type": "email",
    "settings": {
      "addresses": "admin@example.com"
    }
  }'

Verify your monitoring setup

Test that your MinIO monitoring integration is working correctly by checking metrics collection and dashboard functionality.

# Check MinIO metrics endpoint
curl -s http://localhost:9000/minio/v2/metrics/cluster | grep minio_cluster

Verify Prometheus is scraping MinIO

curl -s http://localhost:9090/api/v1/query?query=up{job="minio-job"}

Check Prometheus targets

curl -s http://localhost:9090/api/v1/targets | grep minio

Test Grafana dashboard access

curl -s http://admin:admin@localhost:3000/api/dashboards/db/minio-cluster-monitoring
Note: It may take a few minutes for metrics to appear in Prometheus and Grafana after configuration. The scrape interval determines how often new data is collected.

Advanced monitoring configuration

Enable MinIO audit logging

Configure audit logging for comprehensive security and access monitoring beyond basic performance metrics.

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=your-secure-password-here
MINIO_VOLUMES=/data/minio
MINIO_OPTS="--console-address :9001"
MINIO_PROMETHEUS_AUTH_TYPE=public
MINIO_AUDIT_WEBHOOK_ENDPOINT=http://localhost:8080/audit
MINIO_AUDIT_WEBHOOK_AUTH_TOKEN=audit-token-here

Configure custom metrics collection

Add additional Prometheus jobs for collecting MinIO node-specific metrics and custom application metrics.

  - job_name: 'minio-node-metrics'
    metrics_path: /minio/v2/metrics/node
    scheme: http
    static_configs:
      - targets: ['localhost:9000']
    scrape_interval: 30s

  - job_name: 'minio-bucket-metrics'
    metrics_path: /minio/v2/metrics/bucket
    scheme: http
    static_configs:
      - targets: ['localhost:9000']
    scrape_interval: 60s

Security considerations

When deploying MinIO monitoring in production, consider implementing authentication for the metrics endpoint and encrypting communications between components. For comprehensive security hardening, refer to our MinIO security guide.

Security Warning: The configuration above uses public access to metrics. In production, implement proper authentication using MINIO_PROMETHEUS_AUTH_TYPE=jwt and configure appropriate access tokens.

Common issues

SymptomCauseFix
Metrics endpoint returns 404Prometheus metrics not enabledVerify MINIO_PROMETHEUS_AUTH_TYPE=public in environment file
Prometheus shows target as downNetwork connectivity or wrong portCheck MinIO is running on port 9000: sudo netstat -tlnp | grep 9000
No data in Grafana dashboardPrometheus data source misconfiguredVerify Prometheus URL in Grafana data source settings
High memory usage alertsIncorrect memory metrics interpretationUse minio_cluster_usage_total_bytes for storage, not memory usage
Dashboard panels show no dataMetric names changed between versionsUpdate panel queries to match current MinIO metric names
Alerts not firingAlerting rules syntax errorsValidate YAML syntax: promtool check rules /etc/prometheus/minio_alerts.yml

Next steps

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.