Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

VGPU-Mon

CICodeQLMIT License

VGPU-Mon is a native Windows GPU task manager written in C. It combines direct Windows per-process video-memory queries, WDDM engine counters, DXGI, and NVIDIA NVML to show board telemetry and the processes consuming each GPU.

It is a real full-screen terminal application, not a wrapper around nvidia-smi. NVML is loaded dynamically, so the same executable still runs on AMD and Intel systems with the vendor-neutral data that Windows exposes.

Features

  • Live GPU and physical VRAM utilization with driver-reserved memory separated
  • Full-screen timestamped charts with time-span zoom, history panning, and exact hover values
  • Direct per-process dedicated/shared GPU-memory usage, with a validated WDDM fallback for protected processes
  • Per-process 3D, compute, copy, encode, and decode engine activity
  • Temperature, board power, power limit, fan, P-state, and clocks through NVML
  • Encoder, decoder, and PCIe link/throughput telemetry when the driver exposes it
  • Multiple-GPU switching
  • Mouse-clickable sort headers and process rows, plus context-aware wheel navigation
  • Responsive layouts with bounded full-frame repainting after every terminal resize
  • Interactive sorting, process-name filtering, and process details
  • Confirmed process termination with protection for system and self PIDs
  • Pause/resume and adjustable 250-5000 ms refresh interval
  • CSV logging
  • One-shot human-readable and JSON output for scripts
  • Automatic, checksum-verified background updates for installed interactive launches
  • Statically linked MSVC runtime; no NVML SDK or third-party runtime required

Runtime requirements and compatibility

  • 64-bit Windows 10 version 1809 or newer, or Windows 11
  • A WDDM 2.x display driver for direct per-process memory queries and per-engine Windows counters
  • Windows Terminal is recommended for the interactive interface
  • A current NVIDIA display driver for temperature, power, clocks, fan, encoder/decoder, and NVML memory accounting

No CUDA Toolkit, NVML SDK, Visual C++ Redistributable, Python, or administrator access is required at runtime. The release executable statically links the C runtime and dynamically discovers NVML in both supported Windows driver locations: System32 for DCH drivers and Program Files\NVIDIA Corporation\NVSMI for standard drivers.

Modern GeForce/RTX, Quadro/RTX professional, and data-center NVIDIA GPUs generally receive the full feature set when the installed driver exposes those calls. NVIDIA documents only limited NVML support for non-data-center GPUs, so not every NVIDIA GPU/driver combination exposes every sensor. Unsupported values appear as N/A or Unavailable, not as fabricated readings.

Under NVIDIA TCC mode, old pre-WDDM 2.x drivers, some VMs, or remote sessions, NVML board telemetry may work while Windows per-process and engine counters do not. AMD and Intel adapters receive DXGI/WDDM data but not NVIDIA-only sensors.

Visual Studio 2022 C++ Build Tools are needed only to build from source.

Some protected processes cannot be inspected or terminated without elevation. VGPU-Mon reports their GPU accounting normally when Windows exposes it, but does not bypass Windows security.

Install

Open PowerShell or Windows Terminal and paste this one command:

curl.exe-fsSL https://raw.githubusercontent.com/xptea/VGPU-Mon/main/install.ps1 |Out-String|Invoke-Expression

The bootstrap script finds the latest stable GitHub Release, downloads its per-user installer and SHA256SUMS.txt, verifies the installer SHA-256, and only then runs it silently. It does not require administrator access. Open a new terminal tab after installation, then run:

vgpu
vgpu --chart vram
vgpu --chart 3d
vgpu --json

Existing terminal processes keep their old environment. Uninstalling VGPU-Mon from Windows Settings removes the PATH entry only when the installer originally added it.

Starting with VGPU-Mon 1.2.0, an installed interactive launch checks the latest stable release's small version.txt manifest. If a newer version exists, VGPU-Mon downloads that exact versioned installer, verifies its SHA-256 with Windows cryptography, and installs it without elevation. The command then returns cleanly; run vgpu again after a few seconds to start the updated monitor. The updater deliberately does not relaunch inside the old terminal because the shell would already own that terminal's input. Network or GitHub failures do not prevent the monitor from opening. Redirected output and script commands (--json, --once, --version, and --demo) never perform an automatic update check.

Use vgpu --update to check immediately. Use --no-update for one launch or set VGPU_MON_NO_UPDATE=1 to disable automatic checks. Portable ZIP copies do not update silently; vgpu --update converts a portable copy into the normal per-user installation.

Prefer to inspect scripts before running them? Read install.ps1, or download the versioned installer/portable ZIP manually from Releases. Release assets include SHA256SUMS.txt. Windows SmartScreen may warn about community-built releases until the project has a trusted code-signing certificate; always verify the download came from this repository.

Build and run

Install Visual Studio 2022 with Desktop development with C++. Include the optional C++ AddressSanitizer component if you want to run the sanitizer gate. From PowerShell:

.\build.ps1 -Configuration Release -Test
.\run.ps1

The build script discovers Visual Studio through vswhere, initializes the correct x64 native toolchain, and writes build\vgpu-mon.exe.

A CMake target is also provided for IDEs and static-analysis tooling:

cmake -S .-B build\cmake -A x64
cmake --build build\cmake --config Release --parallel
ctest --test-dir build\cmake -C Release --output-on-failure

The full local quality gates are:

.\build.ps1 -Configuration Debug -Test
.\build.ps1 -Configuration Release -Test
.\build.ps1 -Configuration Sanitize -Test -OutputName vgpu-mon-asan
.\analyze.ps1
.\tools\verify-pe.ps1

Debug tests enable the MSVC CRT leak detector. The sanitizer build runs the same native, ConPTY, and CLI tests under MSVC AddressSanitizer. /analyze warnings fail the build. The PE check verifies ASLR, DEP, CFG, CET compatibility, and the absence of a dynamic MSVC runtime dependency. GitHub Actions repeats these checks and runs CodeQL on every change to main.

To create the portable release ZIP:

.\package.ps1

To build the Windows installer, install Inno Setup 6 and run:

winget install --id JRSoftware.InnoSetup --exact --scope user
.\installer.ps1

Interactive controls

KeyAction
Up / DownSelect a process
PgUp / PgDnMove by ten rows
uSort by busiest GPU engine
mSort by dedicated VRAM
sSort by shared memory
p, n, eSort by PID, name, or engine
oReverse the current sort
Mouse clickSort a header or select a process row
Mouse wheelMove through process rows; zoom the time span over a chart
Shift + mouse wheelPan backward or forward through chart history
Left / RightPan a chart by one-quarter of its visible span
PgUp / PgDnPan a chart by one full visible span
Home / EndJump to the oldest complete chart window or return live
Mouse hoverShow the exact chart value and how long ago it was sampled
fEdit the process-name filter
dToggle details for the selected process
iToggle the full GPU information panel
cToggle full-screen chart/table view
1-0Select GPU, VRAM, engine, temperature, or power chart
kAsk to terminate the selected process
lToggle CSV logging to vgpu-mon.csv
[ / ]Switch GPU
+ / -Refresh faster or slower
SpacePause or resume sampling
hToggle help
qQuit

Script-friendly output

.\build\vgpu-mon.exe--once
.\build\vgpu-mon.exe--json
.\build\vgpu-mon.exe--gpu 0--interval 500--json |ConvertFrom-Json

Demo mode

--demo feeds deterministic sample telemetry through the real renderer, input loop, charts, and JSON code without querying GPU hardware. It is useful for evaluating the UI, reproducing terminal bugs, and automated testing:

.\build\vgpu-mon.exe--demo
.\build\vgpu-mon.exe--demo --chart vram
.\build\vgpu-mon.exe--demo --json

Demo values are clearly labeled and must not be treated as machine telemetry.

Full-screen charts

.\build\vgpu-mon.exe--chart
.\build\vgpu-mon.exe--chart vram
.\build\vgpu-mon.exe--chart 3d
.\build\vgpu-mon.exe--chart copy
.\build\vgpu-mon.exe--chart decode
.\build\vgpu-mon.exe--chart encode
.\build\vgpu-mon.exe--chart compute
.\build\vgpu-mon.exe--chart memory-controller
.\build\vgpu-mon.exe--chart temperature
.\build\vgpu-mon.exe--chart power

The flag form requested by the UI is also supported, such as --chart --vram, --chart --3d, or simply --vram. In chart view, number keys switch metrics without restarting and c returns to the process table.

Charts open on a one-minute live window. Scroll the mouse wheel over the plot to zoom from a tighter view to the full retained range. Use Shift+wheel, Left/Right, or PgUp/PgDn to inspect older samples; End snaps back to live data. Hovering anywhere on the plot draws a crosshair and an in-chart tooltip with the nearest real sample's value and age.

VGPU-Mon retains 14,400 timestamped samples per metric in a fixed-size ring, so memory use stays bounded. That represents about four hours at the default one-second interval, one hour at 250 ms, or twenty hours at five seconds. Stored timestamps keep zoom, panning, and hover ages correct when the sampling interval changes during a run. History is in memory only and resets when the app closes or the selected GPU changes; use CSV logging for long-term storage.

Options:

--once Print one snapshot and exit
--json Print one snapshot as JSON
--chart [METRIC] Open a full-screen chart
--vram, --percent Open a VRAM or overall-utilization chart
--3d, --copy, --decode, --encode, --compute
Open a WDDM engine chart
--gpu INDEX Select a physical GPU
--interval MS Sampling interval from 250 to 5000
--log PATH Start CSV logging when interactive mode opens
--demo Use deterministic sample data for previews and tests
--update Check for and install an update now
--no-update Skip the automatic update check for this run
--help Show help
--version Show the version

Data sources and accounting

  • D3DKMT video-memory queries provide current local and non-local usage for each accessible process on the selected adapter. VGPU-Mon resolves the documented Windows entry points dynamically and opens adapters using their DXGI LUIDs.
  • Windows GPU performance counters discover active GPU processes, provide per-process engine utilization, and supply a guarded memory fallback when Windows does not allow the process handle needed by the direct API. The displayed process percentage is that process's busiest engine, which follows Windows Task Manager's accounting model.
  • DXGI 1.4 enumerates hardware adapters, supplies the LUID used by the direct memory provider, and reports local video-memory usage and the current OS memory budget.
  • NVML supplies NVIDIA board telemetry. VGPU-Mon uses the versioned memory API to separate driver/firmware-reserved VRAM from application allocation. nvml.dll is discovered and loaded at runtime; the project does not ship NVIDIA libraries.

VRAM figures from D3DKMT, NVML, DXGI, and WDDM can differ because they describe different accounting layers. Shared allocations may be attributed to more than one process, so adding every row is not a physical-board total. VGPU-Mon marks process columns with * and keeps the physical total and OS budget separate.

Windows' GPU Process Memory performance counter can accumulate stale allocations and produce implausibly large values. Those counters are no longer the primary memory source. If a protected process requires the fallback, VGPU-Mon validates only that row, marks a rejected value as N/A !, writes a blank CSV field or JSON null, and raises wddm_process_memory_warning without hiding valid rows. Physical board usage at the top remains sourced from NVML/DXGI.

JSON reports dedicated_memory_source and shared_memory_source as d3dkmt, pdh, demo, or unavailable. The generic dedicated_memory_bytes and shared_memory_bytes fields are authoritative. The older JSON aliases and CSV column names ending in _commit_bytes remain for compatibility; their source columns identify whether the value came from the direct API or the guarded fallback.

Terminating a process is not the same as resetting a GPU. VGPU-Mon deliberately does not expose driver resets or unsafe attempts to cancel individual command queues.

JSON, CSV, screenshots, and bug reports can expose process names, executable activity, paths, or GPU identifiers. Review and redact telemetry before sharing it.

Contributing and security

VGPU-Mon is released under the MIT License.

Technical references

About

Native Windows GPU process monitor in C with WDDM, DXGI, and NVIDIA NVML telemetry

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages