---
title: "Monitor multiple databases | Database Observability documentation"
description: "Configure Database Observability to monitor multiple database instances with deployment patterns and labeling strategies."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Monitor multiple databases

As your infrastructure grows beyond a single database, you need to monitor multiple database instances. This guide covers deployment patterns, configuration strategies, and labeling best practices for managing multiple databases with Database Observability.

## Before you begin

Complete setup for at least one database:

- [Set up MySQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/mysql/)
- [Set up PostgreSQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/postgres/)

You also need:

- Grafana Alloy running and connected to Grafana Cloud
- Grafana Cloud remote write credentials for Prometheus and Loki

## Choose a deployment pattern

Choose a deployment pattern based on your infrastructure and scale requirements.

### Single Alloy instance

One Alloy instance monitors all databases.

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
┌─────────────────┐
│  Grafana Alloy  │
│    ┌─────────┐  │     ┌──────────┐
│    │ MySQL 1 │──┼────▶│ mysql-1  │
│    ├─────────┤  │     └──────────┘
│    │ MySQL 2 │──┼────▶│ mysql-2  │
│    ├─────────┤  │     └──────────┘
│    │ PG 1    │──┼────▶│ postgres │
│    └─────────┘  │     └──────────┘
└────────┬────────┘
         │
         ▼
   Grafana Cloud
```

**Advantages:**

- Simple to deploy and manage
- Single configuration file
- Lower resource overhead

**Disadvantages:**

- Single point of failure
- Network latency to remote databases
- Scaling limits

**Best for:**

- Small to medium deployments (&lt; 20 databases)
- Databases in same network/region
- Development and staging environments

### Distributed Alloy instances

Deploy Alloy alongside each database or group of databases.

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
┌────────────┐    ┌────────────┐    ┌────────────┐
│  Region A  │    │  Region B  │    │  Region C  │
│ ┌────────┐ │    │ ┌────────┐ │    │ ┌────────┐ │
│ │ Alloy  │ │    │ │ Alloy  │ │    │ │ Alloy  │ │
│ │   ↓    │ │    │ │   ↓    │ │    │ │   ↓    │ │
│ │ MySQL  │ │    │ │ PG     │ │    │ │ MySQL  │ │
│ └────────┘ │    │ └────────┘ │    │ └────────┘ │
└─────┬──────┘    └─────┬──────┘    └─────┬──────┘
      │                 │                 │
      └─────────────────┼─────────────────┘
                        ▼
                  Grafana Cloud
```

**Advantages:**

- High availability (one Alloy failure doesn’t affect others)
- Low latency to local databases
- Scales horizontally
- Aligns with infrastructure boundaries

**Disadvantages:**

- More instances to manage
- Distributed configuration
- Higher total resource usage

**Best for:**

- Large deployments (20+ databases)
- Multi-region infrastructure
- Production environments requiring high availability

## Configure multiple databases

### Single Alloy with multiple databases

Add a component block for each database:

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
// ====================
// Database 1: MySQL orders
// ====================

local.file "mysql_orders_secret" {
  filename  = "/var/lib/alloy/mysql_orders_dsn"
  is_secret = true
}

prometheus.exporter.mysql "orders" {
  data_source_name  = local.file.mysql_orders_secret.content
  enable_collectors = ["perf_schema.eventsstatements"]
}

database_observability.mysql "orders" {
  data_source_name = local.file.mysql_orders_secret.content
  forward_to       = [loki.relabel.orders.receiver]
  targets          = prometheus.exporter.mysql.orders.targets
}

loki.relabel "orders" {
  forward_to = [loki.write.default.receiver]
  
  rule {
    target_label = "instance"
    replacement  = "orders.db.example.com:3306"
  }
  rule {
    target_label = "job"
    replacement  = "integrations/db-o11y"
  }
  rule {
    target_label = "app"
    replacement  = "order-service"
  }
}

discovery.relabel "orders" {
  targets = database_observability.mysql.orders.targets
  
  rule {
    target_label = "job"
    replacement  = "integrations/db-o11y"
  }
  rule {
    target_label = "instance"
    replacement  = "orders.db.example.com:3306"
  }
  rule {
    target_label = "app"
    replacement  = "order-service"
  }
}

prometheus.scrape "orders" {
  targets    = discovery.relabel.orders.output
  forward_to = [prometheus.remote_write.default.receiver]
}

// ====================
// Database 2: PostgreSQL users
// ====================

local.file "pg_users_secret" {
  filename  = "/var/lib/alloy/pg_users_dsn"
  is_secret = true
}

prometheus.exporter.postgres "users" {
  data_source_names  = [local.file.pg_users_secret.content]
  enabled_collectors = ["stat_statements"]
  autodiscovery {
    enabled = true
  }
}

database_observability.postgres "users" {
  data_source_name = local.file.pg_users_secret.content
  forward_to       = [loki.relabel.users.receiver]
  targets          = prometheus.exporter.postgres.users.targets
}

loki.relabel "users" {
  forward_to = [loki.write.default.receiver]
  
  rule {
    target_label = "instance"
    replacement  = "users.db.example.com:5432"
  }
  rule {
    target_label = "job"
    replacement  = "integrations/db-o11y"
  }
  rule {
    target_label = "app"
    replacement  = "user-service"
  }
}

discovery.relabel "users" {
  targets = database_observability.postgres.users.targets
  
  rule {
    target_label = "job"
    replacement  = "integrations/db-o11y"
  }
  rule {
    target_label = "instance"
    replacement  = "users.db.example.com:5432"
  }
  rule {
    target_label = "app"
    replacement  = "user-service"
  }
}

prometheus.scrape "users" {
  targets    = discovery.relabel.users.output
  forward_to = [prometheus.remote_write.default.receiver]
}

// ====================
// Shared outputs
// ====================

prometheus.remote_write "default" {
  endpoint {
    url = "https://prometheus-prod-01-us-east-0.grafana.net/api/prom/push"
    basic_auth {
      username = sys.env("GRAFANA_CLOUD_PROMETHEUS_USERNAME")
      password = sys.env("GRAFANA_CLOUD_API_KEY")
    }
  }
}

loki.write "default" {
  endpoint {
    url = "https://logs-prod-us-east-0.grafana.net/loki/api/v1/push"
    basic_auth {
      username = sys.env("GRAFANA_CLOUD_LOKI_USERNAME")
      password = sys.env("GRAFANA_CLOUD_API_KEY")
    }
  }
}
```

### Mixed database types

You can monitor both MySQL and PostgreSQL from the same Alloy instance:

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
// MySQL databases
database_observability.mysql "mysql_1" { /* ... */ }
database_observability.mysql "mysql_2" { /* ... */ }

// PostgreSQL databases
database_observability.postgres "pg_1" { /* ... */ }
database_observability.postgres "pg_2" { /* ... */ }
```

Each component is independent and can have different configurations.

## Choose a labeling strategy

Consistent labels help you filter and organize databases in Database Observability dashboards.

### Required labels

These labels must be set correctly for Database Observability to function:

Expand table

| Label      | Requirement                    | Example                      |
|------------|--------------------------------|------------------------------|
| `instance` | Unique per database            | `orders.db.example.com:3306` |
| `job`      | Must be `integrations/db-o11y` | `integrations/db-o11y`       |

### Recommended labels

Add these labels to organize and filter databases:

Expand table

| Label         | Purpose           | Example values                        |
|---------------|-------------------|---------------------------------------|
| `app`         | Application name  | `order-service`, `user-api`           |
| `team`        | Owning team       | `checkout`, `platform`                |
| `environment` | Deployment stage  | `production`, `staging`, `dev`        |
| `region`      | Geographic region | `us-east-1`, `eu-west-1`              |
| `cluster`     | Database cluster  | `orders-primary`, `orders-replica`    |
| `provider`    | Cloud provider    | `aws`, `gcp`, `azure`, `self-managed` |

### Label consistency

Labels must match between `loki.relabel` and `discovery.relabel`:

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
// Logs labels
loki.relabel "mydb" {
  rule {
    target_label = "instance"
    replacement  = "mydb.example.com:3306"
  }
  rule {
    target_label = "environment"
    replacement  = "production"
  }
}

// Metrics labels - must match!
discovery.relabel "mydb" {
  rule {
    target_label = "instance"
    replacement  = "mydb.example.com:3306"  // Same value
  }
  rule {
    target_label = "environment"
    replacement  = "production"  // Same value
  }
}
```

For complete label guidance including best practices, environment variables, and troubleshooting, refer to the [Labels reference](/docs/grafana-cloud/monitor-applications/database-observability/reference/labels/).

## Add cloud provider integrations

Add a `cloud_provider` block in Grafana Alloy to correlate database telemetry with infrastructure metrics from AWS CloudWatch, Azure Monitor, or Google Cloud Monitoring. The block also enables the Cloud Provider Observability integration in Database Observability.

Configure Alloy using the platform setup guides:

- [AWS RDS MySQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/mysql/rds/), [AWS Aurora MySQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/mysql/aurora/), [AWS RDS PostgreSQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/postgres/rds/), [AWS Aurora PostgreSQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/postgres/aurora/)
- [Azure Database for MySQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/mysql/azure/), [Azure Database for PostgreSQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/postgres/azure/)
- [Google Cloud SQL MySQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/mysql/cloudsql/), [Google Cloud SQL PostgreSQL](/docs/grafana-cloud/monitor-applications/database-observability/set-up/postgres/cloudsql/)

The following examples show the `cloud_provider` block for each platform.

### AWS RDS / Aurora

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
database_observability.mysql "rds" {
  data_source_name = local.file.rds_secret.content
  forward_to       = [loki.relabel.rds.receiver]
  targets          = prometheus.exporter.mysql.rds.targets
  
  cloud_provider {
    aws {
      arn = "arn:aws:rds:us-east-1:123456789012:db:mydb"
    }
  }
}
```

### Azure Database

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
database_observability.postgres "azure" {
  data_source_name = local.file.azure_secret.content
  forward_to       = [loki.relabel.azure.receiver]
  targets          = prometheus.exporter.postgres.azure.targets
  
  cloud_provider {
    azure {
      subscription_id = "your-subscription-id"
      resource_group  = "your-resource-group"
      server_name     = "your-server-name"
    }
  }
}
```

### Google Cloud SQL

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
database_observability.mysql "cloudsql" {
  data_source_name = local.file.cloudsql_secret.content
  forward_to       = [loki.relabel.cloudsql.receiver]
  targets          = prometheus.exporter.mysql.cloudsql.targets

  cloud_provider {
    gcp {
      connection_name = "my-project:us-central1:my-db"
    }
  }
}
```

The `connection_name` value is the Cloud SQL instance connection name in `project:region:instance` format. You can find it in the Google Cloud console on the instance details page.

The `cloud_provider` block also enables integration with [Cloud Provider Observability](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/). For navigation between query performance and cloud infrastructure metrics, refer to **Access Database Observability** in the Cloud Provider Observability documentation for your platform:

- [Preconfigured dashboards and alerts](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/aws/cloudwatch-metrics/metric-dashboards/#access-database-observability)
- [Preconfigured dashboards and alerts for Azure metrics](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/azure/azure-alerts/#access-database-observability)
- [Google Cloud Platform observability](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/gcp/#access-database-observability)

## Troubleshoot multi-database setups

When databases don’t appear or data doesn’t correlate correctly, start with these multi-database-specific checks:

1. Verify that every database has a unique `instance` label.
2. Confirm the `instance` value matches exactly between the `loki.relabel` and `discovery.relabel` blocks for the same database.
3. Check that `job` is exactly `integrations/db-o11y` on every component.

For detailed troubleshooting steps, refer to the dedicated guides:

- [Troubleshoot Alloy](/docs/grafana-cloud/monitor-applications/database-observability/troubleshoot/alloy/)
- [Troubleshoot MySQL](/docs/grafana-cloud/monitor-applications/database-observability/troubleshoot/mysql/)
- [Troubleshoot PostgreSQL](/docs/grafana-cloud/monitor-applications/database-observability/troubleshoot/postgres/)

## Related documentation

- [Tune Alloy collection](/docs/grafana-cloud/monitor-applications/database-observability/configure/tune-alloy-collection/): Optimize per-database settings
- [Labels reference](/docs/grafana-cloud/monitor-applications/database-observability/reference/labels/): Complete label documentation
- [Verify telemetry status](/docs/grafana-cloud/monitor-applications/database-observability/configure/verify-telemetry-status/): Validate configuration health per database
