Back to blog

How I Replaced Windows With a Hypervisor and Got a Better Windows

17 min read technology personal

It all started innocently enough — with 128 gigabytes of RAM that I got through work. Sounds impressive as a number, but for a workstation it's frankly excessive. And it was precisely this excess that pushed me down a path that ended with a complete OS reinstall, virtualizing everything, and getting better performance than I had without a hypervisor.

But first — a small digression.

From Linux to Windows: the prodigal son's journey

I used to be a Linux fanboy. Thanks to my university professor — a man who seemed to worship Linux. A joke about Windows during his lectures could earn you a decent grade, and a genuine interest in the kernel — an even better one. It was because of him that I started actively using Linux: first Ubuntu, then Fedora, then Arch — the classic path of escalation.

At first it was exciting — finding and solving problems, customizing the system, breaking and fixing things, breaking them again. But at some point I realized a simple truth: constantly configuring everything to your liking is hard, and eventually it gets tiresome. One wrong command can break your system, and you're back with a live USB reinstalling everything from scratch. Time that could've gone to work or rest was spent fighting drivers, configs, and dependencies.

So I decided to install Windows 11. And you know what? I liked it. WSL 2 covered most of my Linux needs — Docker, Python, Node.js, SSH tunnels, everything runs natively inside Windows. Then I discovered PowerToys — a set of tools from Microsoft where they test various useful features before integrating them into the OS (at least that's what I think — some of those features do end up in Windows updates). FancyZones, PowerRename, Peek, Always On Top — I recommend it to everyone on Windows. Free, open source, and it significantly improves daily workflow.

So there I was, on Windows 11, with WSL 2, generally satisfied. Until those 128 GB of RAM showed up.

RAM disk: a good idea that didn't fly

When you have 128 GB of RAM and actually use 30–50 GB during work, a natural question arises: what do you do with the rest? First idea — RAM disk.

The concept was simple: keep projects with lots of files on a RAM disk, get read/write speeds at RAM levels, and enjoy life. And indeed — for projects with thousands of small files, the difference was instant. npm install, git status, builds — everything flew.

But there are caveats. Many caveats.

First, a RAM disk lives until shutdown. Turn off the computer — lose everything. In Ukraine, where power outages happen regularly, one accidental blackout could wipe out a chunk of your work. I set up rsync backup scripts every 15 minutes, but still — losing even 15 minutes of work to a power cut is unpleasant.

Second, compatibility. The main issue that killed this idea — uv (the modern Python package manager from Astral, replacing pip/virtualenv) refused to build packages on the RAM disk due to file system compatibility issues. For a Head of Data who lives in Python, this was critical.

Third, side effects. I moved all temporary folders (TEMP, browser cache) to the RAM disk. Chrome seemed to work better visually — cache reads were instant. But the system overall behaved oddly: stability was around 6–7 out of 10, and Windows Explorer opened slowly, as if it couldn't find something at startup.

Verdict: more problems than benefits. The idea was buried.

First encounter with Proxmox VE

At some point, through work and forums, I started noticing articles about Proxmox VE — an open-source virtualization platform. I'd actually heard about it only recently, even though I was well familiar with KVM, OpenVZ, Virtuozzo, VMware, and VirtualBox — I'd encountered these tools in various contexts.

I skeptically skimmed a few articles. Then I asked AI for a detailed breakdown — and that's where it hooked me. The key points I heard:

  • Lightweight. Proxmox VE is essentially Debian with a thin virtualization management layer. The hypervisor itself consumes minimal resources
  • Very flexible. Full KVM support for full virtualization and LXC for containers
  • PCI passthrough. You can pass physical devices — GPUs, network cards, USB controllers — directly into a virtual machine. The VM sees the device as native, no emulation, near-metal performance
  • ZFS and ARC cache. Built-in ZFS support with adaptive caching in RAM

Essentially, I had nothing to lose except my time. And when time goes toward something interesting — I don't even regret it if things don't work out.

Preparation and installation

I dug up my old graphics card — ASUS HD6670 1 GB DDR3, vintage 2014. A card without GOP and UEFI support — an absolute placeholder, but that's exactly what I needed: output the Proxmox terminal through it so I wouldn't touch the main GPU. The primary GPU — AMD RX 580 8 GB — would go entirely to the virtual machine via PCI passthrough.

Downloaded the Proxmox VE ISO, flashed it with Rufus — and encountered a maximally friendly installation. During which I learned about one of the key features that would later transform my PC experience.

ZFS ARC: why I need all that RAM

During installation, Proxmox offered a file system choice — and I picked ZFS. This was one of the best decisions.

ZFS ARC (Adaptive Replacement Cache) is a caching mechanism built into the ZFS file system. The concept is simple: ZFS uses free RAM as a cache for data read from disk. The first read comes from the physical drive, and after that — from RAM. And it doesn't just cache recent files like most operating systems do, but uses an adaptive algorithm that distinguishes between:

  • MRU (Most Recently Used) — files that were read recently
  • MFU (Most Frequently Used) — files that are read often

ARC automatically balances between these two strategies, adapting to the workload. The result — minimal physical disk access after the initial warm-up, maximally efficient use of RAM.

And here's where my 128 GB of RAM found their true purpose. Instead of an artificial RAM disk that needs manual population and backup, ZFS ARC automatically turns free memory into an ultra-fast disk cache. The system decides what to cache on its own, and when a VM needs more memory — ARC automatically frees up space.

It's not a RAM disk. It's smarter.

First impressions: web UI, mobile app, and installing Windows from bed

Installation went smoothly. After rebooting, I was greeted by the Web UI — a full-featured hypervisor management panel accessible from any device on the network. Terminal, mobile app — everything available immediately. I was surprised, especially by the mobile app and the ability to launch noVNC — a full virtual machine console right from your phone.

Not without its issues — working with a console on a small screen isn't the most comfortable, better through the web interface from a proper browser. But the fact remains: from the mobile app, I managed to install Windows from scratch — create a VM, attach the ISO, launch the installation, and go through it via noVNC while lying in bed. Big plus — you can disconnect all monitors and manage everything from your phone.

Three days to a working system

Day one: everything default, everything slow

First impression of Windows in a VM was frankly — not great. Everything worked, but it felt "sluggish" — delays on clicks, micro-stutters, slow app launches. System rating — around 4 out of 10.

The problem was that I'd left everything at defaults: emulated display adapter, emulated network controller, standard disk controller. Proxmox defaults to emulating devices for maximum compatibility, but emulation always means overhead.

Day two: first optimizations

Started tweaking settings. Installed VirtIO drivers — paravirtualized drivers for network, disks, video, memory. VirtIO is a standard that lets the guest OS "know" it's running in a VM and communicate with the hypervisor directly, without emulating physical devices. The difference in disk I/O speeds was dramatic.

Passed through the main devices via PCI passthrough:

  • GPU AMD RX 580 8 GB — as the primary video card for the VM
  • WiFi Intel AX210 — along with Bluetooth
  • USB controller — for keyboard, mouse, and peripherals

The system improved to 6–7 out of 10 — noticeably better, but still slightly worse than without the hypervisor. The main issue — some devices were passed through incorrectly: some were emulated instead of passthrough, while others locked the host because they were already "claimed" by the VM.

Day three: reinstall with proper settings

Decided to reinstall everything from scratch, but with correct settings from the start. And here I was pleasantly surprised.

The system started working better than on bare-metal Windows. Micro-stutters disappeared. Response became crisper. Apps opened faster. Rating — a solid 8–9 out of 10.

What I did differently:

CPU: fewer cores — higher frequency. Following Claude Opus's recommendation, I reduced the number of allocated cores for the VM but allowed them to run at full turbo boost frequency. The logic is simple: most desktop tasks depend on single-threaded performance, not core count. Plus, I assigned the VM physical CPU cores while leaving Hyper-Threading for other VMs and the host. This minimized resource contention and let the CPU run at maximum frequency.

RAM: 64 GB for VM, the rest for ARC. Allocated 64 GB for the Windows VM — with headroom, since I rarely loaded more than 50 GB during work. The remaining memory automatically went to ZFS ARC, turning the disk into a rocket.

NUMA topology. Enabled NUMA (Non-Uniform Memory Access) in VM settings. NUMA informs the guest OS about the processor's real memory topology — which cores have direct access to which memory banks. Without this, the VM might try to read memory through a "foreign" controller, adding latency. With NUMA — each core works with its nearest memory.

Hugepages (1 GB memory pages). The standard memory page size in x86 is 4 KB. For a VM with 64 GB of RAM, that's millions of entries in the page table that the processor must handle. Hugepages increase the page size to 2 MB or even 1 GB, reducing entries by thousands of times. Fewer entries — less load on the TLB (Translation Lookaside Buffer) — faster memory access.

Disabled power saving. In BIOS and Proxmox settings, I disabled C-States, P-States, Cool'n'Quiet, and other power-saving mechanisms. For a desktop workstation running on mains power, there's no point sacrificing performance for 20W savings. The CPU always runs at full frequency, with no delays from "waking up" from sleep states.

Linux under the hood: why it matters

There's another factor I initially underestimated. Proxmox VE is Debian Linux under the hood. This means all hardware management — CPU scheduler, memory management, I/O scheduler, drivers — runs through the Linux kernel. And this is where one of the main secrets of the improved performance lies.

The Linux kernel has historically been better at working with hardware directly. The process scheduler distributes load across cores more efficiently. The I/O scheduler better optimizes disk request queues. Kernel-level drivers in Linux work closer to the hardware, without Windows Driver Model abstractions. Memory management — especially with ZFS and hugepages — produces less fragmentation and lower latency.

Essentially, I got the best of both worlds: raw Linux performance for hardware management and a familiar Windows desktop experience for daily work. Windows thinks it's running on dedicated hardware, but in reality there's a thin Linux hypervisor layer between it and the physical CPU/memory/disk that does the job more efficiently than Windows itself on bare metal. The irony is that Linux, which I once left for the sake of convenience, now quietly runs under the hood making my Windows better.

The dual GPU hack

A separate point — how I organized display output. The HD6670 is connected to one of the monitors via VGA and displays the Proxmox console. The main RX 580 is passed through to the Windows VM via PCI passthrough and connected via HDMI/DisplayPort.

I wrote a small script that pings the QEMU Guest Agent inside the VM: when Windows is running and GPU drivers are initialized — the monitor automatically switches to HDMI (output from RX 580). When the VM is off — it switches back to VGA (Proxmox console via HD6670). This way, I always have access to the hypervisor, even when the VM is running.

CrystalDiskMark: numbers that don't make sense (but are telling)

Once the system was running stable, I decided to run some standard benchmarks. First up — CrystalDiskMark.

Results for my no-name NVMe PCIe 3.0 512 GB drive (C:) — 6656 MB/s read, 1625 MB/s write in sequential Q8T1 test. For my RAID 1 from two SATA SSDs (F:) — 7041 MB/s read, 11002 MB/s write.

Wait, what? 11 GB/s write on SATA SSDs? That's physically impossible — SATA III has a ceiling of 600 MB/s per drive.

The answer — ZFS ARC. CrystalDiskMark writes and reads a test file, but ZFS caches that file in RAM after the first access. Subsequent iterations read not from disk but from RAM. Essentially, the benchmark is testing RAM speed, not disk speed.

For real disk performance testing, CrystalDiskMark in a ZFS environment doesn't work. But it vividly demonstrates that ARC is working: any file read once is subsequently served at RAM speed. For real tasks — opening projects, launching an IDE, compiling — this means repeated operations happen instantly.

AIDA64 produced even crazier numbers in its tests — I simply ignored the results since they had zero relation to real-world performance.

Elden Ring on max settings: an unexpected side effect

Then, just for fun, I decided to launch Elden Ring. Brief note on my top games: Heroes of Might and Magic 3 (WoG), Red Alert 2: Yuri's Revenge, and Elden Ring. Nothing super new or demanding, but I barely have time for games.

Previously, Elden Ring barely ran on minimum settings — I had to drop the resolution to 1080p on my 2K monitor just to have something playable. The RX 580 at 8 GB — it's no longer the card for modern games, especially with DX12.

So I launch the game in the VM. Went through the tutorial and only then noticed that the game was running in 2K on high settings. I'd simply forgotten to go into settings and drop everything to minimum. And yet — zero micro-stutters, FPS held steadily above 50.

Checked Task Manager — GPU was at 60–70% load. Set everything to maximum — load went up to 80–90%, but everything ran just as smoothly. I was pleasantly surprised.

Why does the GPU work better in a VM?

This seems paradoxical — how can a graphics card in a virtual machine perform better than on bare metal? But there's a logical explanation.

When the RX 580 is passed through via PCI passthrough, the VM gets direct, exclusive access to the GPU. No emulation, no intermediate layer — the GPU works as if it's physically installed in the computer running that VM.

But the key difference is in what's absent. On bare-metal Windows, the graphics card serves dozens of processes simultaneously:

  • Desktop Window Manager (DWM) — compositing all windows, transparency, animations
  • Windows Search Indexer — generating thumbnails and previews
  • Hardware-accelerated browsing — Chrome/Edge use GPU for page rendering
  • Windows Defender — GPU-accelerated scanning
  • Multiple monitors — desktop rendering on each
  • OBS, Discord overlay, Steam overlay — if running
  • Background driver updates and AMD/NVIDIA telemetry

In the VM — clean Windows with minimal background processes. The GPU is dedicated exclusively to the current task. No competition for VRAM, no context switching between dozens of GPU processes. Plus, Proxmox as the Linux host doesn't use this GPU at all — it has its own HD6670.

Additionally, ZFS ARC caches game files after first load. Repeated loads of levels, textures, shaders — at RAM speed, not NVMe speed. This reduces the stutter from asset streaming, which is one of Elden Ring's main issues.

The result — the GPU runs at full power without "parasitic" OS overhead, while data flies at RAM speed. For an aging RX 580, this turned out to be a significant boost.

macOS: Flutter builds without Hackintosh pain

Besides Windows, I installed macOS in a separate VM. I'm not a fan of this OS — it's pretty, has many useful features, but Apple's policies irritate me a bit. And my fingers are already wired for Windows shortcuts. The only reason I need macOS — building Flutter apps for iOS. Without macOS you can't build an .ipa file — Apple doesn't allow it, and there's no way around it.

Found a guide on GitHub — following the instructions, everything booted up but without GPU support. The AMD RX 580, while supporting Metal through macOS drivers on real hardware, works with limitations in a VM. This is one reason I still keep the RX 580 and haven't replaced it with something like an RTX 5060 — AMD has better support in macOS virtualization, even if incomplete. Running iOS Simulator or any app requiring Metal GPU acceleration — no chance.

With some struggle, I managed to pass through the GPU, and without any issues upgraded to macOS Tahoe 26.3. Everything worked at a level sufficient for building a project.

Compared to Hackintosh — this was 100 times simpler. No hours with Custom SSDT/DSDT, no picking kexts, no writing ACPI patches for specific hardware, no fear of macOS updates. Proxmox just creates a VM, and macOS thinks it's running on a real Mac.

Downside: to switch between the Windows and macOS VMs, you need to completely shut down one and start the other — since both use the same GPU through PCI passthrough. With only one discrete GPU available for VMs, simultaneous operation is impossible.

What I got in the end

Let's sum up. I replaced bare-metal Windows with the Proxmox VE hypervisor running a Windows VM, and here's what I have:

Better performance. Windows with fewer cores, less RAM (64 GB instead of 128 GB) — but a more stable system with better responsiveness. The GPU runs cleaner, the CPU runs at maximum frequency, and drives fly thanks to ARC.

Snapshots and quick rollback. Before a Windows update, before installing sketchy software — one click for a snapshot. If something goes wrong — rollback in seconds. No need to restore from backup, no need to reinstall. It's like git for your operating system.

Phone management. Proxmox Mobile App + noVNC — start, stop, monitor VMs from any device. I can't yet power on the PC from my phone — need to set up Wake-on-LAN or install a Zigbee module with Home Assistant for power control.

Dedicated Docker VM. This is probably one of the biggest wins. Docker Desktop on Windows is a constant headache with serious performance impact. On Proxmox, I created a separate lightweight VM specifically for Docker — isolated, no conflicts, no WSL2 overhead.

Isolated environments for AI agents. The ability to run AI agents (OpenClaw etc.) in fully isolated VMs — no risk to the main system, full control over resources.

macOS for iOS builds. Flutter projects build for iOS without a separate Mac and without Hackintosh acrobatics.

Is it worth the hassle?

Three days of setup — that's not nothing. Maybe all of this could've been solved without a hypervisor: put Docker on WSL2, forget about the RAM disk, live with micro-stutters. But I like this approach — because I have more control.

Control over how many resources each task gets. Control over what runs and what doesn't. The ability to snapshot before any change and roll back in seconds. The ability to run three different operating systems on one machine without rebooting (well, almost — there's only one GPU for VMs for now).

If you have spare time and curiosity for this kind of thing — give it a try. Proxmox VE is free, the documentation is excellent, and the community is active. The worst that can happen — you'll spend a weekend and go back to bare-metal Windows. The best — you'll get a system that performs better than the original.

And if you have 128 GB of RAM — ZFS ARC will make your day.

(0)

Comments (0)