From f6e8e67a00a2282f1cd239bfe7b1f5bef2e749af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Fri, 16 Oct 2026 21:33:09 +0200 Subject: [PATCH] docs: explain idle time rates above 1 for logical_disk and physical_disk (#2770) Co-authored-by: Claude Signed-off-by: Claude --- docs/collector.logical_disk.md | 12 +++++++++++- docs/collector.physical_disk.md | 10 ++++++++++ internal/collector/logical_disk/AGENTS.md | 7 +++++++ internal/collector/physical_disk/AGENTS.md | 7 +++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/collector.logical_disk.md b/docs/collector.logical_disk.md index ca109ca2..46e3d855 100644 --- a/docs/collector.logical_disk.md +++ b/docs/collector.logical_disk.md @@ -68,6 +68,16 @@ rate(windows_logical_disk_read_seconds_total[5m]) / rate(windows_logical_disk_re rate(windows_logical_disk_write_seconds_total[5m]) / rate(windows_logical_disk_writes_total[5m]) ``` +### Idle time +`windows_logical_disk_idle_seconds_total` is the `% Idle Time` counter, converted to seconds: the cumulative idle time of the volume. +Windows updates it unevenly while the disk is busy and catches up afterwards, so the rate over a short window can exceed 1 +right after a burst of I/O. Performance Monitor also shows values above 100%. +The errors mostly cancel out over longer windows, but can still push a 5m rate slightly above 1. +Clamp the rate to 1 when you derive the busy time from it: +``` +1 - clamp_max(rate(windows_logical_disk_idle_seconds_total[5m]), 1) +``` + ### Size metrics The `free_bytes` and `size_bytes` metrics are read from the volume on every scrape. Both are the free and total bytes of the whole volume, regardless of NTFS disk quotas of the account running windows_exporter. @@ -141,7 +151,7 @@ Disk Activity + rate(windows_logical_disk_write_seconds_total[2m]) + - rate(windows_logical_disk_idle_seconds_total[2m]) + clamp_max(rate(windows_logical_disk_idle_seconds_total[2m]), 1) ) ``` diff --git a/docs/collector.physical_disk.md b/docs/collector.physical_disk.md index 5e7f1392..215796c3 100644 --- a/docs/collector.physical_disk.md +++ b/docs/collector.physical_disk.md @@ -37,6 +37,16 @@ If given, a disk needs to *not* match the exclude regular expression in order fo | windows_physical_disk_read_write_latency_seconds_total | The time, in seconds, of the average disk transfer (PhysicalDisk.AvgDiskSecPerTransfer) | Counter | disk | +### Idle time +`windows_physical_disk_idle_seconds_total` is the `% Idle Time` counter, converted to seconds: the cumulative idle time of the disk. +Windows updates it unevenly while the disk is busy and catches up afterwards, so the rate over a short window can exceed 1 +right after a burst of I/O. Performance Monitor also shows values above 100%. +The errors mostly cancel out over longer windows, but can still push a 5m rate slightly above 1. +Clamp the rate to 1 when you derive the busy time from it: +``` +1 - clamp_max(rate(windows_physical_disk_idle_seconds_total[5m]), 1) +``` + ### Example metric Query the rate of write operations to a disk ``` diff --git a/internal/collector/logical_disk/AGENTS.md b/internal/collector/logical_disk/AGENTS.md index bde1002c..a983e322 100644 --- a/internal/collector/logical_disk/AGENTS.md +++ b/internal/collector/logical_disk/AGENTS.md @@ -33,6 +33,13 @@ multi-instance. These notes were recorded on a Windows Server 2025 rate(windows_logical_disk_reads_total[5m])`. - `% Idle Time` is a cumulative 100 ns timer as well, not a percentage. On `C:` it was 115960642 ticks, about 11.6 seconds. +- The second raw value of `% Idle Time` is the sample time as a UTC FILETIME; + PDH divides by its delta. Even with that divisor the idle delta of a busy + volume exceeded the elapsed time by up to 16% on `C:` of a Windows 11 NVMe + disk (43% on its `PhysicalDisk` instance) after a 1.6 GB write ended, while idle + disks stayed at 1.000 and `Processor Information` idle time never exceeded 1. + The accumulator lags while busy and catches up later (#1249). The collector + exports the raw counter; queries clamp the rate with `clamp_max(..., 1)`. - `Disk Read Bytes/sec` and `Disk Write Bytes/sec` (`PERF_COUNTER_BULK_COUNT`) and the `PERF_COUNTER_COUNTER` rates are cumulative counts since boot. - `Current Disk Queue Length` is an instantaneous snapshot (gauge) and was 0. diff --git a/internal/collector/physical_disk/AGENTS.md b/internal/collector/physical_disk/AGENTS.md index 285748d8..02aa17fd 100644 --- a/internal/collector/physical_disk/AGENTS.md +++ b/internal/collector/physical_disk/AGENTS.md @@ -19,6 +19,13 @@ multi-instance. These notes were recorded on a Windows Server 2025 (`% Disk Read Time`, `% Disk Write Time`, `% Idle Time`) to seconds. `PERF_AVERAGE_TIMER` values arrive in ticks of the 10 MHz counter time base and need the 1e-7 factor. +- The second raw value of `% Idle Time` is the sample time as a UTC FILETIME; + PDH divides by its delta. Even with that divisor the idle delta of a busy + disk exceeded the elapsed time by up to 43% between 1 s samples on a + Windows 11 NVMe disk (the cooked value of one sample reached 150%) after a 1.6 GB write ended, while idle + disks stayed at 1.000 and `Processor Information` idle time never exceeded 1. + The accumulator lags while busy and catches up later (#1249). The collector + exports the raw counter; queries clamp the rate with `clamp_max(..., 1)`. - The `PERF_AVERAGE_TIMER` base is the operation count: it equals `Disk Reads/sec` (781613), `Disk Writes/sec` (940802) and their sum (1722415).