Boosting Windows 11 with WSL on Proxmox

In my home lab, I rely on Proxmox as my virtualization platform and run it on a powerful AMD Ryzen 9 9950X CPU with 16 cores and a total of 96 GB of RAM. This hardware base offers more than enough reserves to run multiple virtual machines in parallel and cover even more demanding workloads.

For my Windows 11 VM, I deliberately set the CPU type to x86-64-v4 or, alternatively, x86-64-v2-AES in the Proxmox configuration.

In combination with the latest hardware, this setting ensures that Windows runs very close to its native performance.

win11

Another important component is the appropriate Windows VirtIO drivers. These drivers enable the virtual machine to reach its full potential. Thanks to this configuration, the Windows 11 VM is ideal for development work.

Tools such as Visual Studio run reasonably smoothly, and even larger projects can be edited without noticeable delays.

For a quick overview of system performance, simple benchmarks can be performed in Windows using the Winsat (Windows System Assessment Tool) to evaluate the performance of the VM.

Here is an example with the CPU configuration shown above and 16GB of RAM.

winsat disk

> Disk  Random 16.0 Read                       826.33 MB/s          8.6
> Disk  Sequential 64.0 Read                   3317.16 MB/s         9.3
> Disk  Sequential 64.0 Write                  3409.08 MB/s         9.3

However, I rely on Docker for software development, as many of the projects are container-based. To use Docker effectively and efficiently on Windows, the Windows Subsystem for Linux (WSL) is indispensable.

Setup WSL and Docker Desktop

Installing WSL is very simple. Open a new terminal as administrator and execute the following command

wsl --install

After successfully installing WSL, you must first restart the virtual machine so that all changes are applied correctly and the necessary system components become active. Only then can Docker Desktop be installed within the Windows VM.

After the second restart, everything seems to be ready: the virtual machine starts up cleanly, Docker Desktop opens, and the next logical step would be to start the actual container development. However, this is precisely where an unexpected problem arises.

Docker cannot be started in this configuration. The reason for this is the CPU emulation used: The configured CPU type x86-64-v4 does not provide hardware virtualization for the Windows VM.

docker

In order for Docker to actually run within the Windows VM, an adjustment must be made in the Proxmox configuration.

The previously used CPU type x86-64-v4 must be changed to host.

After restarting, you can also check directly in Windows to see that virtualization is now available correctly. In Task Manager, under Performance, it is explicitly displayed that virtualization is active.

docker2

However, another look at the performance measurements with Winsat reveals an unpleasant finding:

The results for read and write operations are now significantly worse than before. This drop in performance is particularly noticeable in I/O-heavy workflows 🫩.

winsat disk

> Disk  Random 16.0 Read                       144.87 MB/s          7.4
> Disk  Sequential 64.0 Read                   641.51 MB/s          8.2
> Disk  Sequential 64.0 Write                  1151.43 MB/s         8.5

This is obviously bad if you have to work with Visual Studio or Rider.

Fix CPU Config

After some experimentation and help from my “AI friends” and Google, I finally came across an optimized Proxmox configuration that supports both Docker and Windows in the VM with high performance. The key settings are as follows:

args: -cpu host,svm,aes,pcid,spec-ctrl,hv_relaxed,hv_vapic,hv_vpindex,hv_time,hv_synic,hv_stimer,hv_reenlightenment,hv_frequencies
cpu: host

A new WinSAT test now shows significantly improved values 🍻

winsat disk

> Disk  Random 16.0 Read                       769.59 MB/s           8.6
> Disk  Sequential 64.0 Read                   3841.00 MB/s          9.4
> Disk  Sequential 64.0 Write                  2294.82 MB/s          9.1

To implement the optimization described above, the configuration of the corresponding VM in Proxmox must be adjusted. This can be done directly via the command line: nano /etc/pve/qemu-server/100.conf.

agent: 1
args: -cpu host,svm,aes,pcid,spec-ctrl,hv_relaxed,hv_vapic,hv_vpindex,hv_time,hv_synic,hv_stimer,hv_reenlightenment,hv_frequencies
cpu: host
balloon: 0
bios: ovmf
boot: order=scsi0;net0
cores: 20
efidisk0: local-workloads:vm-100-disk-0,efitype=4m,ms-cert=2023,pre-enrolled-keys=1,size=4M
machine: pc-q35-10.1
memory: 16000
meta: creation-qemu=10.1.2,ctime=1765131411
name: win11-test
net0: virtio=BC:24:11:29:E5:C5,bridge=vmbr0,firewall=1,tag=10
numa: 1
ostype: win11
scsi0: local-workloads:vm-100-disk-2,aio=threads,cache=writeback,iothread=1,size=50G
scsihw: virtio-scsi-single
smbios1: uuid=fefa54d2-0c4b-44ad-ac8e-79045ccd362c
sockets: 1
tpmstate0: local-workloads:vm-100-disk-1,size=4M,version=v2.0
vga: qxl
vmgenid: a81bf0f1-ad54-4df4-a7ea-6b61fff8f2ae

Further information on CPU flags and types: