I have a docker compose setup that consists of:
- wordpress:php8.1
- mariadb:latest
- traefik:v2.7
To rule out Windows networking differences, this is the benchmark ran from inside:
curl --resolve example.com:443:172.18.0.3 --write-out '%{time_total}n' --output /dev/null https://example.com
Where example.com is my custom domain, the IP is traefik container’s current IP. I’m running the command SSH’d into VMware, and then from PowerShell after typing wsl
. I copied the project from one place to the other as-is (kudos to Docker for portability).
It consistently returns ~0.2s for the VMware-backed instance, while it’s 0.4-0.6s for WSL. It represents the load of the index.php itself which includes HTML source of a performant WP site, using a handcoded theme, no plugins. Locally, the staticized version doesn’t seem to have a measurable difference, or very slight, all under 10ms on both systems.
Rest of the config:
- Windows 11 22H2 22610.1, WSL 2, VMware 16.1.0 build-17198959, Docker installed the same way and NOT Docker Desktop.
- UFW off.
- The vmdk and vhdx files are on the same SSD.
- Not using /mnt files across filesystems: everything is under the home folder of each system, respectively.
- OS is Ubuntu 20.04.4 LTS in WSL, and Ubuntu 21.10 in VMware. I tried Ubuntu 22.04 LTS in WSL and WMware too, same numbers.
- I even tried with Nginx + PHP-FPM variant of WP in WSL, and OpenLiteSpeed in VMware, nothing changes the numbers.
- The only difference I know of is that I had to
sudo update-alternatives --config iptables
and choose/usr/sbin/iptables-legacy
to make Docker work in WSL, which on WMware I didn’t need to do.
3
Answers
There are known networking bottlenecks in WSL2.
See this GitHub issue for potential workarounds: https://github.com/microsoft/WSL/issues/4901
Some solutions that have worked for others:
Several caveats with my answer:
That said, I’m going to report the data that I came up with in investigating this.
Short summary — My benchmarking seems to show a substantial disk IO and memory performance delta between Hyper-V and VMWare that likely explains your WordPress results.
Supporting data and research
I started out with a similar test scenario as yours, but attempted to reduce it to as much of an MRE as I could:
Configuration
Hardware:
Virtualization:
In both WSL2 and VMWare:
ubuntu:latest
(22.04) Docker imageNote that for the benchmarking below:
Benchmarking
I started off with some basic Sysbench testing of CPU and Memory. This was done from within the Docker container.
A simple
sysbench cpu --time=300 run
:Pretty much an even matchup there.
sysbench memory run
:Ouch – WSL2’s Docker image is running at about 10% of the memory bandwidth of VMWare. I’ll be honest; it was tough to spot this until I inserted the comma separators here in the table ;-). At first glance, I thought the two were on par.
I decided to skip straight to MySQL testing, also using Sysbench, since this would probably provide the closest match to your WordPress usage. This was done (after a corresponding
prepare
) with:I’ll skip the histogram and second-by-second results (but I have them saved if they are useful to anyone), but here’s the summary data:
Again, ouch — WSL2’s MySQL performance (in Docker, at least) is benchmarking at around a tenth of that of VMWare. It’s likely that most of your observed performance difference is represented in these results.
At this point, I began to suspect that the problem could be reproduced in a more generic (IO) way at the hypervisor level, ignoring WSL2 and Docker entirely. WSL2, of course, runs inside a (hidden to the user) Hyper-V backed VM, even though it doesn’t require the full Hyper-V manager.
I proceeded to enable Hyper-V and install another Ubuntu 20.04 guest in it. I then installed Sysbench in both the VMWare and Hyper-V guest Ubuntu OS.
I then ran a disk IO comparison with:
The results bore out the suspicion:
One interesting thing to note during this stage was that the
prepare
operation for Sysbench was faster on Hyper-V by about 30% (IIRC). I did not capture the results since theprepare
step isn’t supposed to be part of the benchmarking.However, after reading your comment and benchmarking results on
unzip
being faster on WSL2, I’m thinking there may be a connection. Both VMWare and Hyper-V/WSL2 use dynamically resized virtual disks (sometimes called "sparse"). The size of the virtual disk on the host OS essentially starts as a near-0-byte file and grows as needed up to its maximum size.It may be that either:
I cannot say for sure exactly which order I did things in, and the only way to know for sure would be to "shrink/compress" the virtual disks and try again.
Summary
It appears, to my naïve eye and at least on the "Pro" level of Windows, that Hyper-V has some serious performance limitations when compared to VMWare.
Tuning attempts and other comparisons
I did attempt some tuning of the Hyper-V system, but I’m no expert in that area. Regardless, there’s not much that we as users could do to extend any Hyper-V tuning to WSL2 — Microsoft would have to make most of those changes.
I did try converting the dynamic VHDX to a fixed one, in hopes that it would increase IO, but it did not make a substantial change either.
I’ve also now also tried:
Disabling swap in WSL2
Running the Sysbench tests with more threads
Setting a fixed 12GB RAM size for WSL2.
Running sysbench under WSL2 on my primary desktop, which has faster memory and an NVMe drive compared to my test system’s SSD.
Next steps
It would be great if you could, perhaps, run some similar benchmarking apart from your WordPress instance, since you already have the two environments set up. If we can corroborate the data, we should probably report it to, at least, the WSL team. They can hopefully either provide some guidance on how to tune WSL2 to near parity with VMWare, or work with the Hyper-V team on this.
Again, it does seem surprising to me that the disparity between Hyper-V and VMWare is so great. I still struggle to believe that I myself am not doing something wrong in the benchmarking.
After taking a nice look into
wsl
and classic VMs and refreshing my memory a little bit, I have reached a theory, but I cannot prove it.I hope this answer helps in anyway or attracts someone with a direct knowledge of this question.
I asked here in the comments and to myself:
Is it possible that Hyper-V is just configured to use much less % of ‘raw power’ than VMWare? (I.E: Microsoft giving WSL not a lot of priority compared to windows and windows getting almost all the available resources) Or is it a more intrinsic problem with Hyper-V performance (coding etc)?
This comes from my own understanding that WSL seems to be more intended for accessing linux commodities from windows but not for a resource-intensive (including network speed) activity like hosting a webpage. Due to how WSL is integrated, it seems intuitive to think that it will run faster than a typical VM, but a VM is fully configurable, you can almost give it full access to resources.
If you look at these answers, you can see that it doesn’t really seem to be intended to replace a VM per se.
So I think that WSL probably is not configured to these kind of tasks, neither it is meant to be configurable enough to change that.
I think that the main usage Microsoft was aiming with WSL was to give windows users a dinamic workflow in which you could switch between Windows and Linux commodities (since, IMHO, Linux is much better in console commodities than Windows), but NOT to make WSL a full-fledged VM with all of it’s characteristics. It also makes sense since, why would you want to make, for example, a webpage and host it in a linux environment that has the burden of sharing resources with a windows environment you are not using AND that it is the ‘main’ one?