DCGM: NVIDIA's datacenter GPU monitoring stack

What DCGM is, why nvidia-smi isn't enough for production monitoring, the components (host engine, dcgmi, dcgm-exporter, DCGM-Diag), the field IDs and XID codes you actually want to alert on, and how it integrates with Prometheus and the GPU Operator.

Try the commands on this page in the command emulator — type help for the full list, or solutions for copy-paste fix recipes.

nvidia-smi is for humans poking at one node. DCGM (Data Center GPU Manager) is the monitoring API NVIDIA gives you for fleets — it exposes counters that nvidia-smi doesn't, has stable metric names, runs as a daemon, and ships a Prometheus exporter. If you're operating more than ~5 GPUs in production and you're not running DCGM, you are flying blind. This page is what to install, what to scrape, and what to alert on.

Why DCGM exists

nvidia-smi's output is a snapshot serialized as text. It works, but:

  • It can only be invoked one node at a time. No remote access without your own SSH fan-out.
  • Counters reset every time you call it; deltas need to be computed externally.
  • The most operationally interesting counters — XID error history, NVLink lane errors with recovery counts, ECC remap pool state, profiler-grade SM occupancy — aren't exposed.
  • Output is human-readable, not machine-stable. Field rename-related breakage hits monitoring scripts on every driver bump.

DCGM solves all four. It's a long-running daemon (nv-hostengine) that uses NVML + a profiler API to track everything the GPU exposes, with a stable field-ID API and a few CLIs / exporters on top.

Architecture

                     ┌─────────────────────────────┐
                     │       nv-hostengine         │   the daemon (one per node)
                     │  ─ NVML access              │
                     │  ─ profiler counters        │
                     │  ─ XID watcher              │
                     │  ─ field-ID API             │
                     └─────────────────────────────┘
                              │   │   │
            TCP 5555 / IPC    │   │   │
        ┌─────────────────────┘   │   └────────────────────┐
        ▼                         ▼                        ▼
   dcgmi (CLI)            dcgm-exporter            Custom apps
   diag, dmon, group       Prometheus              libdcgm.so

Modes:

  • Embedded mode — daemon runs as a library inside another process (older Bright Cluster Manager, custom apps).
  • Standalone modenv-hostengine runs as a systemd service. This is what every modern deployment uses.

Components

ComponentBinary / artifactWhat it does
Host enginenv-hostengineThe daemon. Polls GPUs, maintains time-series internally
Shared librarylibdcgm.soC API for any consumer
dcgmiCLIHealth, group, diag, dmon, profiling subcommands
dcgm-exportercontainer / binaryPrometheus scraper that talks to nv-hostengine
DCGM-Diagdcgmi diagActive health checks (run levels 1/2/3/4)
Python bindingspydcgmQuick scripting for ops

Install on Ubuntu:

$ apt install datacenter-gpu-manager-4
$ systemctl enable --now nvidia-dcgm
$ systemctl status nvidia-dcgm --no-pager
● nvidia-dcgm.service - NVIDIA DCGM service
     Active: active (running)

If you run the GPU Operator on Kubernetes, DCGM + dcgm-exporter come bundled — you don't install them by hand.

dcgmi quick tour

# enumerate GPUs as DCGM sees them
$ dcgmi discovery -l
1 GPU found.
+--------+----------------------------------------------------------------------+
| GPU ID | Device Information                                                  |
+========+======================================================================+
| 0      | Name: NVIDIA H100 80GB HBM3                                         |
|        | PCI Bus ID: 00000000:1B:00.0                                        |
|        | Device UUID: GPU-1234abcd-…                                          |
+--------+----------------------------------------------------------------------+

# live monitor — like `nvidia-smi dmon` but with stable fields
$ dcgmi dmon -e 100,140,150,155,156,1004,1005 -d 1000
# GPU   POWER  GPUTL  MCUTL  TMPTR  TMEM  TENSO  DRAMA
    0   145    96     78     54     54    72     61

# health snapshot of a group of GPUs
$ dcgmi health -g 0 -c
Health Monitor Report
+------------------+------------+----------------------------------+
| GPU ID           | Status     | Recommendation                  |
+==================+============+==================================+
| 0                | Healthy    |                                  |
| 1                | Healthy    |                                  |
+------------------+------------+----------------------------------+

DCGM-Diag — active health checks

dcgmi diag -r N runs synthetic load and validates outputs. Run levels:

LevelDurationWhat it doesWhen to use
-r 1secondsSoftware / config sanity (driver loaded, NVML OK, no obvious issues)Bringup smoke test, every node boot
-r 2~2 minutesMemory + compute + PCIe quick stress, NVLink, basic thermalPre-job health check, post-RMA validation
-r 3~10-30 minutesDeeper stress, sustained load, more thermal headroom probing, GPU-burn-styleAcceptance test for new nodes, after suspicious XIDs
-r 4hoursFull burn-in (newer DCGM)Post-install acceptance; rarely in steady state
# typical pre-job check: "does this node deserve a 24h training run"
$ dcgmi diag -r 2

Successfully ran diagnostic for group.
+---------------------------+---------------------------------------------+
| Test Name                 | Result                                      |
+===========================+=============================================+
| Deployment                | Pass                                        |
| Memory                    | Pass                                        |
| Hardware                  | Pass                                        |
| Stress                    | Pass - All                                  |
+---------------------------+---------------------------------------------+

Failures point you at a specific subsystem. A Memory test failure that complains about ECC uncorrectable events on GPU 3 → that GPU is suspect; pull it from the schedulable pool, run -r 3, decide RMA.

Field IDs you actually want to scrape

DCGM uses numeric field IDs. The full list lives in /usr/include/dcgm_fields.h — it's long. Here are the ones that pay rent in production:

Field IDNameWhat it tells youAlert?
100DCGM_FI_DEV_SM_CLOCKSM clock MHzDrop = throttle
110DCGM_FI_DEV_MEMORY_TEMPHBM temp> 90 °C critical
140DCGM_FI_DEV_GPU_TEMPCore temp> 85 °C warn
150DCGM_FI_DEV_POWER_USAGEWatts> TDP for sustained
155DCGM_FI_DEV_GPU_UTILGPU util %Low + high power = problem
156DCGM_FI_DEV_MEM_COPY_UTILMemory copy util %-
200DCGM_FI_DEV_FB_FREEFramebuffer free MiBOOM precursor
203DCGM_FI_DEV_FB_USEDFramebuffer used MiB-
230DCGM_FI_DEV_PCIE_REPLAY_COUNTERPCIe replay eventsYes — PCIe link issue
310DCGM_FI_DEV_XID_ERRORSLast XID codeYes per-XID — see below
391-394NVLink replay/recovery/CRC errorsPer-link NVLink reliabilityYes
409-411NVLink bandwidth (TX/RX)Per-link throughput-
419-422ECC SBE/DBE volatile + aggregateECC errorsDBE = critical
1004DCGM_FI_PROF_SM_ACTIVETrue SM active fraction (profiler-grade)The real "GPU util"
1005DCGM_FI_PROF_SM_OCCUPANCYSM occupancy %Capacity planning
1006DCGM_FI_PROF_PIPE_TENSOR_ACTIVETensor Core active fraction"Is the tensor core actually being used"
1009DCGM_FI_PROF_DRAM_ACTIVEHBM active fractionMemory-bound check
1011DCGM_FI_PROF_PCIE_TX_BYTESPCIe trafficTraffic class
1012DCGM_FI_PROF_PCIE_RX_BYTES""
1015DCGM_FI_PROF_NVLINK_TX_BYTESNVLink trafficSanity for NCCL

The 1xxx block is profiler-grade and gives you the truth that 155 (DCGM_FI_DEV_GPU_UTIL) only approximates. For training jobs, watch 1004 SM_ACTIVE and 1006 TENSOR_ACTIVE — if both are low while util is "100%", the kernel is launch-bound or memory-bound.

XID codes — what to alert on

XID is an NVRM kernel log code. DCGM exposes the latest one as field 310; the kernel log keeps the full history. Critical XIDs operators should page on:

XIDMeaningAction
13Graphics Engine ExceptionOften app bug; investigate but not always RMA
31GPU memory page faultUsually app bug (out-of-bounds access)
43GPU stopped processingReset GPU, watch for repeats
44Graphics Engine fault during context switchDriver / hardware issue
45Preemption-induced GPU resetUsually benign
48Double Bit ECC ErrorPull from schedule, run diag -r 3
56-58Display Engine errorsMostly irrelevant on datacenter SKUs
61Internal micro-controller breakpoint / warningInvestigate; can precede 79
62Internal micro-controller haltHardware faulting, prep for RMA
63-64Row remapping (correctable / pending)Memory aging; track trend
69BAR1 access failureSoftware / fabric issue
74NVLink errorPull from schedule, check fabric
79GPU has fallen off the busPage now, node is down
92High single-bit ECC rateMemory aging; preventative action
94Contained ECC error (Hopper+)Application-level recovery possible
95Uncontained ECC errorGPU reset required
119/120GSP RPC timeout / GSP haltGSP firmware misbehaving; reload driver / reboot

Reference: https://docs.nvidia.com/deploy/xid-errors/index.html.

A reasonable alerting matrix:

  • Page: 48, 62, 74, 79, 95, 119, 120.
  • Ticket: 43, 44, 63, 64, 69, 92, 94 — accumulate, escalate on repeat.
  • Log only: 13, 31, 45 — usually app issues, not infra.

dcgm-exporter + Prometheus

dcgm-exporter is the bridge to Prometheus. It runs as a sidecar to nv-hostengine and serves /metrics.

# trimmed view of the metric output
DCGM_FI_DEV_GPU_TEMP{gpu="0",UUID="GPU-…"}        54
DCGM_FI_DEV_POWER_USAGE{gpu="0"}                  148
DCGM_FI_DEV_FB_USED{gpu="0"}                      512
DCGM_FI_PROF_SM_ACTIVE{gpu="0"}                   0.96
DCGM_FI_PROF_PIPE_TENSOR_ACTIVE{gpu="0"}          0.71
DCGM_FI_DEV_XID_ERRORS{gpu="0"}                   0
DCGM_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_TOTAL{...}  0
DCGM_FI_DEV_ECC_DBE_AGG_TOTAL{gpu="0"}            0

Customize which fields are scraped via dcgm-exporter's csv config. The default set is fine for 90% of cases; add the 1xxx profiler IDs explicitly because they're not all on by default (they have a small overhead).

A starter rule set

# Prometheus alerting — minimal viable
groups:
- name: gpu.rules
  rules:
  - alert: GpuFallenOffBus
    expr: changes(DCGM_FI_DEV_XID_ERRORS{xid="79"}[5m]) > 0
    for: 0m
    labels: { severity: page }
    annotations: { summary: "GPU {{$labels.gpu}} on {{$labels.instance}} fell off the bus (XID 79)" }

  - alert: GpuDoubleBitECC
    expr: increase(DCGM_FI_DEV_ECC_DBE_VOL_TOTAL[10m]) > 0
    labels: { severity: page }

  - alert: GpuOverTemp
    expr: DCGM_FI_DEV_GPU_TEMP > 85
    for: 5m
    labels: { severity: warn }

  - alert: GpuMemTempCritical
    expr: DCGM_FI_DEV_MEMORY_TEMP > 95
    for: 1m
    labels: { severity: page }

  - alert: GpuNvlinkReplayCountIncreasing
    expr: increase(DCGM_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_TOTAL[1h]) > 0
    labels: { severity: warn }

  - alert: GpuPcieReplayIncreasing
    expr: increase(DCGM_FI_DEV_PCIE_REPLAY_COUNTER[1h]) > 5
    labels: { severity: warn }

Integration with K8s GPU Operator

The GPU Operator deploys a DaemonSet that includes:

  • NVIDIA driver containerized (or relies on host driver).
  • nv-hostengine running on each GPU node.
  • dcgm-exporter exposed as a service on :9400.
  • ServiceMonitor (if Prometheus Operator is present) to scrape it.

Verifying after install:

$ kubectl -n gpu-operator get pods -l app=nvidia-dcgm-exporter
NAME                              READY   STATUS    RESTARTS   AGE
nvidia-dcgm-exporter-abc12        1/1     Running   0          3d

$ kubectl -n gpu-operator port-forward svc/nvidia-dcgm-exporter 9400 &
$ curl -s localhost:9400/metrics | grep -E "DCGM_FI_DEV_(GPU_TEMP|POWER_USAGE)" | head

Profiling — the more advanced use

dcgmi profile runs the GPU profiler counters more aggressively than the default scrape. Useful for capacity planning ("are these GPUs really being used") but adds non-trivial overhead if all 1xxx fields are sampled at 100ms intervals on a busy GPU. Don't enable everything everywhere; pick a handful and sample at 1s+ in steady state.

$ dcgmi profile --pause
$ dcgmi profile --resume
# pausing useful when running latency-sensitive benchmarks

Common gotchas

  • nv-hostengine and nvidia-fabricmanager race on Hopper/Blackwell. If DCGM starts before the fabric is up, NVLink fields will read zero/error for a few seconds. Set After=nvidia-fabricmanager.service in the DCGM unit override.
  • Persistence mode interacts with DCGM. With persistence off, between-pod GPU resets clear ECC volatile counters, fragmenting your time series. Always run nvidia-persistenced or -pm 1 (see driver).
  • MIG and DCGM. When MIG is enabled, you scrape per-instance metrics. The GPU-level fields are mostly NaN. Configure dcgm-exporter with the MIG-aware label so gpu= and GPU_I_ID= are both present.
  • DCGM diag killed my workload. dcgmi diag -r 3 allocates GPU memory; can't run alongside another big workload. Schedule it to drain windows.

See also