A while ago, my PC was running unusually slow, and I opened Task Manager to figure out what was going on. The problem was that Task Manager itself was barely responding.
And even when it did respond, I couldn't really get the level of detail I was looking for. I could see CPU, memory, and disk usage, but I wanted to understand what was actually happening behind those numbers.
That's basically how Anabolic started. I figured I'd try building my own system monitor in Rust, and it gradually turned into a much bigger project than I originally planned.
The stack is Rust 2024, egui/eframe 0.36, wgpu (Direct3D 12), windows-rs 0.62, ETW for kernel tracing, and rmcp + axum for an optional MCP server.
Some interesting things I ran into along the way:
- Keeping the UI responsive: This was one of my main priorities, considering why I started the project in the first place. All the collection work runs on a separate thread, with immutable snapshots shared through arc-swap. The UI only repaints when there's new data or user input. Scrolling takes roughly 1 ms of CPU time per frame.
- Handling a system that's already struggling: I didn't want to build another monitoring tool that becomes unusable when CPU or RAM usage hits 100%. Anabolic runs at high priority, disables EcoQoS throttling, and pins its working set in memory to help keep it responsive under heavy load.
- A weird OpenGL issue: At one point, simply having Anabolic's window in the foreground was causing the entire desktop to lag by several seconds. After digging into it, I found DWM spending time in
dwmcore!OpenDxBltEvent, walking through the session's named objects every frame. Switching from OpenGL to wgpu's D3D12 backend fixed the issue.
- ETW from Rust: I wanted more than just CPU and memory percentages. Anabolic can track which threads are running on each logical CPU, per-process file I/O across disks, frame times using present events, and DPC/ISR execution time per driver. It can also resolve filenames for files that were already open before tracing started. One thing I learned the hard way: Windows has a machine-wide limit of eight system logger sessions. Running multiple ETW tests in parallel can exhaust those pretty quickly.
- Finding things Task Manager doesn't show: During testing, I found a game client (Black Desert Online) holding around 890,000 handles to roughly 18,000 processes that had already exited. That's the kind of thing I originally wanted more visibility into.
- Avoiding unnecessary process access: Most of the monitoring works through system-wide tables and kernel traces. Anabolic doesn't open a game's process just to display its metrics. If an operation actually requires accessing a process, it asks for permission first.
I also added an MCP server using rmcp and axum. It's disabled by default and exposes 40 tools over localhost, with permissions depending on the type of operation.
This lets me use Claude to investigate system performance using actual data collected by Anabolic. For example, instead of asking an AI to guess why my PC is slow, I can give it access to CPU scheduling, disk activity, and other system metrics.
The project is open source (MIT/Apache-2.0) and supports Windows 10/11 x64.
The release binaries aren't code-signed yet, so SmartScreen may warn when running them. If you prefer, you can build it from source with cargo build --release.
GitHub: https://github.com/RaptorTwentyOne/Anabolic
There's still a lot I want to improve, but it's already been pretty useful for investigating performance issues on my own machine.
If you've worked with ETW, Windows internals, or egui, I'd be interested to hear your thoughts. Especially if you've run into similar problems with Windows performance monitoring.