You can install and configure PostgreSQL monitoring on Kubernetes using the postgresql-otel Helm chart. Optionally, the chart can also run a setup job that creates the monitoring role, its grants, and the pg_stat_statements extension for you.
重要
The chart deploys the collector as a Kubernetes Deployment that reaches PostgreSQL remotely over the network, so it reports PostgreSQL metrics only: no host or infrastructure metrics for the machine PostgreSQL runs on. It monitors one PostgreSQL instance per release (multiple databases on that instance are supported), and it doesn't configure TLS or db_auth credential providers such as AWS IAM authentication.
Server-level prerequisites
PostgreSQL 14 or newer is required. Before installing this chart (or enabling the setup job), the following server parameters must be in place. pg_stat_statements can't be created without shared_preload_libraries, and that parameter requires a restart, so nothing running inside your Kubernetes cluster can do this for you.
Parameter | Value |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
- Self-hosted: set these in
postgresql.conf, then restart PostgreSQL. Some distributions need thepostgresql-contribpackage installed forpg_stat_statementsto be available. - AWS RDS or Aurora: set these in the DB parameter group, not a config file.
track_activity_query_sizeandpg_stat_statements.maxare static parameters; apply them withapply_method: pending-reboot, then reboot the instance. Applying them immediately fails withInvalidParameterCombination. For Aurora, the parameter-group family name must match your engine's major version exactly, for exampleaurora-postgresql16.
Prerequisites
- Valid New Relic license key.
- Helm 3.0 or later, and
kubectlconfigured to access your Kubernetes cluster. - Network connectivity from your Kubernetes cluster to the PostgreSQL host (or RDS endpoint) and port:
- Self-hosted: a routed path to the PostgreSQL host (VPN, peering, or shared network), DNS resolution if it's a hostname, and the PostgreSQL-side
pg_hba.confand firewall must allow the connection's actual source IP (which may be a NAT gateway, not the pod IP itself). - AWS RDS: VPC peering, a transit gateway, or shared-VPC placement with the RDS instance, and the RDS security group must allow the PostgreSQL port (
5432by default) from the cluster's egress source.
- Self-hosted: a routed path to the PostgreSQL host (VPN, peering, or shared network), DNS resolution if it's a hostname, and the PostgreSQL-side
- Either a monitoring role you've already created with its per-database grants, or PostgreSQL admin credentials so the chart's setup job can create them for you. See Configure monitoring credentials below.
Create the namespace
Create the namespace you'll install into. It must exist before you create any secrets in the next step, since helm install --create-namespace only creates the namespace during the final install step:
$kubectl create namespace newrelicヒント
Set it as the default namespace for your current kubectl context so you don't need to pass -n on every command below:
$kubectl config set-context --current --namespace=newrelicConfigure monitoring credentials
Decide whether you want the chart's setup job to create the PostgreSQL monitoring role for you, and if not, how you'll supply its credentials:
Configure the Helm values
Set postgresql.topology to match your environment:
Value | Description |
|---|---|
| Self-hosted PostgreSQL, reached over the network. |
| PostgreSQL or Aurora on AWS RDS. |
postgresql.databases is a required, non-empty list. Unlike MySQL or SQL Server, PostgreSQL has no monitor-every-database mode: a connection targets one database at a time, so the receiver has to be told which ones to scrape.
Use the values.yaml that matches the credential method you chose in the previous step:
Parameter | Description |
|---|---|
| Your New Relic license key. |
| Your region's OTLP/gRPC endpoint, as a bare |
| Your PostgreSQL host (or RDS endpoint) and port, reachable from the cluster. |
| Required, non-empty list of databases to monitor. |
| Databases excluded from cluster-wide top-query and query-sample scans. Defaults to |
| A |
| Optional. Also creates the |
| Optional. Also creates the |
ヒント
You usually don't need to set postgresql.topQueryCollection.explainFunctionName. The receiver's own default is already otel.explain_statement (the exact function setupJob.enableExplainPermissions creates), and the chart omits the key when it's empty, so the two line up with no extra configuration. Set it only to point the receiver at a differently-named function.
ヒント
See the chart's values.yaml for all available configuration options, including postgresql.collectionInterval, the metrics toggles, the topQueryCollection/querySampleCollection blocks, and the additionalReceiverConfig escape hatch.
(Optional) Monitor multiple instances from one release
Instead of postgresql.*, set postgresqlMulti.enabled: true to monitor several PostgreSQL instances (self-hosted or RDS) from a single collector pod in one release. The two modes are mutually exclusive: don't set postgresql.server and postgresqlMulti.enabled: true in the same release.
Entries are called instances, not databases: each instance is a separate PostgreSQL server, and each one carries its own nested databases list (the individual databases to monitor on that instance), the same way postgresql.databases works in single-instance mode.
Multi-instance mode has no plain-username/password path: every instance needs its own Kubernetes secret with monitoring credentials. Decide whether you also want the setup job to create each monitoring role for you:
Parameter | Description |
|---|---|
| Set to |
|
|
| List of instances to monitor. Each entry requires a unique |
ヒント
setupJob.enableExplainPermissions and setupJob.enablePgvector are single toggles shared across every database in every instance; they can't be set per-instance. Scrape settings (collection interval, metrics, topQueryCollection/querySampleCollection) likewise apply identically to every instance in postgresqlMulti.instances; there's no per-instance override. Use additionalReceiverConfig for anything that needs to differ. The setup job runs once per instance (<release>-setup-<name>) rather than once per release.
Install the Helm chart
Add the New Relic Helm repository:
bash$helm repo add newrelic https://helm-charts.newrelic.com$helm repo updateInstall the chart using your
values.yamlfile:bash$helm upgrade --install postgresql-otel newrelic/postgresql-otel \>-n newrelic \>--create-namespace \>-f values.yaml
Verify the installation
Check that the setup job completed (if enabled) and the collector pod is running:
bash$kubectl get jobs,pods -n newrelic --watchRun this query in the query builder to confirm data is arriving:
SELECT count(*) FROM MetricWHERE metricName LIKE 'postgresql.%'AND instrumentation.provider = 'opentelemetry'SINCE 10 minutes ago
Find and use your data
Once your data is being collected, you can access comprehensive PostgreSQL database monitoring through the New Relic UI.
To find your PostgreSQL database entity in New Relic:
- Go to one.newrelic.com > All capabilities > Databases.
- From the Entity type dropdown, select PostgreSQL instance, then click Apply.
- Select your PostgreSQL database from the list of entities.
Related documentation
Introduction to PostgreSQL monitoring with NRDOT
Learn about all the available installation methods for PostgreSQL monitoring with New Relic.
CLI install
Learn how to install and configure PostgreSQL monitoring with a single New Relic CLI command.
Ansible install
Learn how to install and configure PostgreSQL monitoring at scale with the newrelic.newrelic_install Ansible role.
Chef install
Learn how to install and configure PostgreSQL monitoring at scale with the newrelic-install Chef cookbook.