---
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.

**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.

**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

Connect database telemetry with infrastructure metrics from AWS CloudWatch, Azure Monitor, or Google Cloud Monitoring using [Cloud Provider Observability](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/).

Before you begin, configure Cloud Provider Observability to collect metrics for your database’s cloud resource.

**If you edit your Alloy configuration directly:**

1. Add the appropriate `cloud_provider` block from the examples below inside your existing `database_observability.mysql` or `database_observability.postgres` component, or update it if already present.
2. Apply the updated configuration to your Alloy instance.

You can also generate your configuration from the Database Observability **Configuration &gt; Setup** page. For guided setup instructions, Helm values, or complete Alloy configuration examples, refer to your platform’s setup guide:

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

### AWS RDS / Aurora

> Note
> 
> For an Aurora cluster, configure Grafana Alloy separately for each DB instance and connect to its **instance endpoint**. Do not use the cluster (writer), reader, or custom endpoint because these endpoints can route connections to different instances and break metric correlation.

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

```alloy
database_observability.mysql "mysql_<DB_NAME>" {
  data_source_name = local.file.mysql_secret_<DB_NAME>.content
  forward_to      = [loki.relabel.database_observability_mysql_<DB_NAME>.receiver]
  targets         = prometheus.exporter.mysql.mysql_<DB_NAME>.targets

  // Add this block inside your existing database_observability.mysql or database_observability.postgres component.
  cloud_provider {
    aws {
      arn = "<AWS_RDS_INSTANCE_ARN>"
    }
  }
}
```

Replace the placeholders:

- `AWS_RDS_INSTANCE_ARN`: AWS RDS instance ARN for cloud provider integration (for example, `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.mysql "mysql_<DB_NAME>" {
  data_source_name = local.file.mysql_secret_<DB_NAME>.content
  forward_to      = [loki.relabel.database_observability_mysql_<DB_NAME>.receiver]
  targets         = prometheus.exporter.mysql.mysql_<DB_NAME>.targets

  // Add this block inside your existing database_observability.mysql or database_observability.postgres component.
  cloud_provider {
    azure {
      subscription_id = "<AZURE_SUBSCRIPTION_ID>"
      resource_group  = "<AZURE_RESOURCE_GROUP>"
      server_name     = "<AZURE_SERVER_NAME>"
    }
  }
}
```

Replace the placeholders:

- `AZURE_RESOURCE_GROUP`: Azure resource group containing your database server.
- `AZURE_SUBSCRIPTION_ID`: ID of the Azure subscription containing your database server.
- `AZURE_SERVER_NAME`: Name of your Azure database server (optional).

### Google Cloud SQL

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

```alloy
database_observability.mysql "mysql_<DB_NAME>" {
  data_source_name = local.file.mysql_secret_<DB_NAME>.content
  forward_to      = [loki.relabel.database_observability_mysql_<DB_NAME>.receiver]
  targets         = prometheus.exporter.mysql.mysql_<DB_NAME>.targets

  // Add this block inside your existing database_observability.mysql or database_observability.postgres component.
  cloud_provider {
    gcp {
      connection_name = "<CLOUDSQL_CONNECTION_NAME>"
    }
  }
}
```

Replace the placeholders:

- `CLOUDSQL_CONNECTION_NAME`: Cloud SQL instance connection name in `project:region:instance` format (for example, `my-project:us-central1:my-db`). You can find it on the instance details page in the Google Cloud console.

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
