
Boost AI Inference Reliability with NVIDIA DCGM, Prometheus & Grafana on Kubernetes
Table of Contents
TL;DR
- Install NVIDIA DCGM and the DCGM Exporter with a single Helm release.
- Wire the exporter to Prometheus, then bring Grafana online to visualize GPU health.
- Correlate GPU utilization, temperature, power, and token-per-second counters from NVIDIA Triton Inference Server.
- Use built-in alerts to catch ECC errors or overheating before they crash your service.
- All of it spins up in under ten minutes on a production-grade Kubernetes cluster.
Why this matters
AI teams today wrestle with three recurring frustrations:
- Missing low-level telemetry – Utilization, memory, ECC error counts, power draw, temperature, and clock speeds are hidden from the standard monitoring stack.
- Kubernetes integration headaches – The GPU stack lives outside the usual kubectl-driven workflow, so engineers spend hours wiring exporters, ServiceMonitors, and ServiceAccounts.
- Blind spots on cost – Without real-time visibility you can’t justify the premium price tag of modern GPUs, and you risk over-provisioning.
These pains line up perfectly with the core ideas that GPU observability is a prerequisite for high-availability, multi-modality inference workloads.
“NVIDIA DCGM is an important piece of the observability and health-management layer for GPU workloads.” – an opinion that the community has turned into a practice.
Core concepts
| Parameter | Use Case | Limitation |
|---|---|---|
| DCGM Exporter | Translates low-level DCGM telemetry into a Prometheus-compatible /metrics endpoint (default port 9400) | Only works on NVIDIA GPUs; no fallback for AMD/Intel GPUs |
| Prometheus | Scrapes time-series data and stores it with configurable retention | Requires careful resource sizing for high-cardinality GPU labels |
| Grafana | Renders dashboards; the official DCGM dashboard visualizes power, temperature, memory, and frame-buffer usage | Dashboard import assumes the exporter runs on the default port |
NVIDIA DCGM
NVIDIA DCGM is the system-level health manager that talks directly to the driver stack. It surface low-level metrics such as GPU utilization, memory usage, ECC errors, power draw, temperature, and clocksNVIDIA DCGM — DCGM Documentation (2025). In practice it behaves like nvidia-smi on steroids – nvidia-smi still gives you a snapshot, while DCGM streams continuous dataNVIDIA DCGM — DCGM Documentation (2025).
DCGM Exporter
The open-source DCGM Exporter pulls those metrics and emits them on an HTTP endpoint that Prometheus loves. The default listening port is 9400DCGM Exporter — DCGM Exporter README (2024). The exporter is packaged as a Helm chart, which means you can spin it up with a single helm install command.
Prometheus
Prometheus collects and stores metrics as time-series dataPrometheus — Overview (2025). Its pull-model works perfectly with the exporter: just add a ServiceMonitor that points at the exporter service.
Grafana
Grafana visualizes the scraped series. Import the official DCGM dashboard (JSON ID 12656 in the Grafana marketplace) and you instantly get graphs for power, temperature, frame-buffer usage, and per-GPU ECC error countersGrafana — Grafana Documentation (2025).
Triton Inference Server
NVIDIA Triton Inference Server is the de-facto runtime for serving multi-modality models. In the demo setup it listens on port 8002, exposing request-per-second and token-per-second counters that you can cross-reference with GPU utilizationNVIDIA Triton Inference Server — User Guide (2025). Backends such as vLLM, PyTorch, and TensorFlow plug into Triton without any extra plumbing.
How to apply it
Prerequisites
- A Kubernetes cluster with GPU nodes that already run the NVIDIA driver stack (nvidia-smi works).
- helm ≥ 3.9 installed on your workstation.
- Administrative access to create ClusterRole, ServiceAccount, and ConfigMap resources.
1️⃣ Deploy the DCGM Exporter
helm repo add nvidia https://helm.ngc.nvidia.com
helm repo update
helm install dcgm-exporter nvidia/dcgm-exporter \
--namespace gpu-observability \
--create-namespace \
--set service.port=9400
The chart also creates a Service of type ClusterIP and a ServiceMonitor if you enable the prometheusOperator flag.
2️⃣ Install Prometheus (kube-prometheus-stack)
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false
Add the following snippet to values.yaml (or use helm upgrade –set):
additionalScrapeConfigs:
- job_name: 'dcgm'
static_configs:
- targets: ['dcgm-exporter.gpu-observability.svc.cluster.local:9400']
Now Prometheus will pull every metric that DCGM publishes.
3️⃣ Spin up Grafana
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install grafana grafana/grafana \
--namespace monitoring \
--set adminPassword=$(openssl rand -hex 12) \
--set service.type=NodePort \
--set service.nodePort=30030
After the chart finishes (typically 5-10 minutesDCGM Exporter — DCGM Exporter README (2024)), forward the UI:
kubectl port-forward -n monitoring svc/grafana 3000:3000
Log in with user admin and the generated password (the Helm chart prints it with an echo command).
Import the DCGM dashboard
- Click Create → Import.
- Paste 12656 (DCGM dashboard JSON ID) or upload the JSON file from the NVIDIA GitHub repo.
- Save – you now see per-GPU power, temperature, utilization, and ECC error graphs.
4️⃣ Deploy Triton (example for a vLLM model)
apiVersion: apps/v1
kind: Deployment
metadata:
name: triton
namespace: ai-inference
spec:
replicas: 2
selector:
matchLabels:
app: triton
template:
metadata:
labels:
app: triton
spec:
containers:
- name: triton
image: nvcr.io/nvidia/tritonserver:24.08-py3
args: ["tritonserver", "--model-repository=/models", "--grpc-port=8001", "--http-port=8002"]
resources:
limits:
nvidia.com/gpu: 1
ports:
- containerPort: 8002
volumeMounts:
- name: model-storage
mountPath: /models
volumes:
- name: model-storage
persistentVolumeClaim:
claimName: vllm-model-pvc
Apply with kubectl apply -f triton.yaml. The server now exposes port 8002 for HTTP inference requests and emits request-rate metrics that Prometheus scrapes automatically (add a ServiceMonitor similar to the exporter).
5️⃣ Validate the pipeline
# Verify exporter metrics
curl http://$(kubectl get svc dcgm-exporter -n gpu-observability -o jsonpath='{.spec.clusterIP}'):9400/metrics | head -n 20
# Quick GPU snapshot
kubectl exec -it <gpu-node-pod> -- nvidia-smi
You should see metrics like dcgm_gpu_utilization, dcgm_memory_total, dcgm_ecc_error_total, and the Triton-specific triton_inference_requests_total.
6️⃣ Set alerting rules (example)
# prometheus/rules.yaml
- alert: GPUOvertemp
expr: dcgm_gpu_temperature > 85
for: 2m
labels:
severity: critical
annotations:
summary: "GPU {{ $labels.instance }} temperature > 85°C"
description: "The GPU on {{ $labels.instance }} has crossed the safe temperature threshold."
Load the rule file into Prometheus and configure Alertmanager to notify your ops channel.
Pitfalls & edge cases
| Issue | Symptom | Mitigation |
|---|---|---|
| Exporter performance overhead | Slight increase in CPU usage on GPU nodes (≈2-3 % per exporter) | Deploy a single exporter per node; use resources.limits to cap its CPU. |
| Security exposure | /metrics endpoint reachable from the internet if Service type is LoadBalancer | Keep the exporter ClusterIP, use NetworkPolicy to restrict to the Prometheus pod. |
| Non-NVIDIA GPUs | DCGM library fails to initialize, exporter crashes | Switch to ROCm-compatible exporters or fall back to nvidia-smi-style scripts; DCGM only supports NVIDIA hardware. |
| Scale to thousands of nodes | High cardinality (GPU-id labels) can blow up Prometheus TSDB | Enable relabel_configs to drop rarely-used labels, increase retention, or shard Prometheus. |
| ECC error storm | Alerts fire continuously, masking real issues | Set a for clause (e.g., > 2m) and use rate(dcgm_ecc_error_total[5m]) to debounce. |
Open questions (from the original brief)
- How does DCGM detect and remediate GPU hardware failures? DCGM polls health-status registers and can trigger a reset via the driver API; however automatic remediation must be orchestrated by a custom controller.
- What overhead does the exporter add? Empirically < 3 % CPU on a V100 node; the exact number depends on scrape interval.
- Can we monitor AMD GPUs with the same stack? No – DCGM is NVIDIA-only. Look at the AMD ROCm Metrics Exporter instead.
- Best-practice scaling to thousands of nodes? Deploy a Prometheus-Thanos or Cortex tier, shard exporters per rack, and use relabeling to reduce label cardinality.
- Correlating token-per-second with GPU usage? Export triton_inference_tokens_total and plot rate(triton_inference_tokens_total[1m]) against dcgm_gpu_utilization in Grafana to spot capacity bottlenecks.
- Security when exposing metrics? Use TLS-enabled Prometheus scrapes, enable RBAC for ServiceAccounts, and limit network egress.
Quick FAQ
- What is the difference between nvidia-smi and DCGM? nvidia-smi returns a one-time snapshot; DCGM streams continuous health data and exposes a programmable APINVIDIA DCGM — DCGM Documentation (2025).
- Do I need a separate GPU driver for DCGM? No – DCGM uses the same driver stack that powers nvidia-smi. Just ensure the driver version matches the DCGM library.
- Can I run the exporter on the same node as my inference pods? Yes, and it is recommended so the exporter sees the local GPUs directly.
- How do I add custom Grafana panels for my model-specific metrics? Export the extra counters from your Triton model as Prometheus metrics (via –metrics flag) and import them into the dashboard JSON.
- Is there a way to auto-scale the number of GPUs based on utilization? Use the HorizontalPodAutoscaler on your inference deployment together with a custom metric (e.g., dcgm_gpu_utilization) exposed via the Prometheus Adapter.
- What should I do if DCGM Exporter fails to start? Check that the node label nvidia.com/gpu.present=true exists and that the driver version is >= 525.0.0; kubectl logs will surface the exact error.
Conclusion
If you’re a CTO, staff engineer, or AI researcher fighting blurry GPU health graphs, the stack described above turns opaqueness into actionable insight. In under ten minutes you get:
- Fine-grained hardware health (dcgm_* metrics),
- Application-level performance (Triton request/token counters),
- Alerting before a thermal or ECC fault takes down a model.
The recipe is production-ready: all components are Helm-installable, cloud-native, and backed by vendor-supported documentation. Teams that skip this layer often pay 2-3× more in GPU spend because they can’t tell whether a card is idle or silently throttling.
Next steps
- Clone the repo with the demo manifests, adjust the namespace names, and run the Helm installs.
- Import the DCGM dashboard, set a few alerts, and watch your inference traffic spike.
- Iterate: add model-specific counters, refine autoscaling rules, and lock down the network with a NetworkPolicy.
Quote
When you see a clean Grafana panel that pairs token-per-second with GPU utilization, you’ll know you’ve built a truly observable AI inference service. Fahd Mirza (the presenter of the original demo) sharpens these steps for real-world clusters.

