Background

I recently joined the Windows Insider Program, on the slow ring, to be able to test a development version of the soon-to-be-released Windows Subsystem for Linux, version 2, henceforth WSL 2.

Microsoft is doing fantastic work integrating Linux with their Windows operating system.

I find it personally quite useful being able to do native Linux development on the Windows partition of my ThinkPad, whilst still having access to all of the native Windows applications that I sometimes need to use.

With WSL 2, they now ship a full Linux kernel with Windows.

Users are able to start light-weight Linux containers within a light-weight utility Hyper-V VM, and all of this with dynamic memory allocation and reclaim.

Goal

Because the code that I work on generally lives on the Windows filesystem, synced by Dropbox, I wanted to test the performance of WSL2 manipulating files on the NTFS filesystem.

Furthermore, because WSL2 now runs with its own EXT4 filesystem on a virtual hard disk, I also wanted to test the performance of WSL2 on that.

In this post, I show the results of comparing the performance of WSL 1 and WSL 2 on their respective “local” and NTFS (host) files, and of native Linux 5.3 on the same hardware, via four different IO-heavy tests.

Methods

For this experiment, I used Windows Version 2004 build 19035.1000 on a ThinkPad X1 Extreme with 32GB of RAM and a Samsung 970 Evo Plus 1TB NVMe SSD.

The four tests are:

  1. yarn build create-react-app: Use webpack and babel to build the basic open source create-react-app. This generates about 40KB of gzipped code.
  2. yarn build tsnsi: Use webpack and typescript to build a large proprietary application that I work on most days. This generates about 40MB of minimized javascript code. This repo contains just over 100000 files. THANKS node_modules!
  3. du -sh tsnsi: Calculate disk usage over the 100000 small files in the proprietary project.
  4. du -sh cpbotha.net: Calculate disk usage over my personal blog’s hugo source files. 4700 files of varying sizes occupying about 780MB.

In all but one case (du tsnsi on WSL2 NTFS, because the spread was just too great), I ran the test multiple times, and recorded the average time in seconds. After the first run, standard deviation was low.

In all cases, the built-in Microsoft anti-virus real-time protection was disabled, as that can have a significant effect on IO-based benchmarks.

Results

Test WSL 1 ntfs WSL 2 ntfs WSL 2 samba WSL 1 lxfs WSL 2 ext4 native linux
yarn build c-r-a 11.89 63.14 13 7.38 5.8 4.63
yarn build tsnsi 45.25 263.71 65 31.70 28.75 24.13
du tsnsi 4.9 70 - 155 (4x) 13.5 8.6 0.19 0.19
du cpbotha.net 0.24 3.7 0.5 0.074 0.011 0.015

Discussion

  • Native Linux on the same hardware is the fastest.
  • WSL 2 using its local EXT4 filesystem is very close to native Linux performance.
  • WSL 2 using its built in NTFS support (going via the 9p service exposed by the Window host) is unusably slow. As a rule of thumb, WSL 2 accessing host (NTFS) files is about 5 times slower than WSL 1 accessing those same files.
  • Mounting the NTFS filesystem using Linux’s samba / cifs support in the WSL 2 container gets you timings that are 4x faster than the built-in 9p NTFS access, but still between 0.25x and 2x slower than WSL 1’s built-in support for accessing Windows files.
  • WSL 1 on its “local” filesystem, lxfs, is in most cases quite usable. However, this sometimes also suffers from NTFS’s bad file locking behaviour.

Microsoft is aware of the slowness of accessing Windows files from WSL 2, as can be seen in this document, in which you can find the following section:

Cross OS file speed will be slower in initial preview builds

You will notice slower file speeds compared to WSL 1 when accessing Windows files from a Linux application, or accessing Linux files from a Windows application. This is a result of the architectural changes in WSL 2, and is something that the WSL team is actively investigating on how we can improve this experience.

In this github issue you can see more discussion and measurements.

Conclusion

If you often need to work with files on NTFS, use WSL 1 until WSL 2 catches up.

However, if there’s any way for you to copy your files to the WSL 2 local filesystem and work there, that’s the fastest option with a significant margin.

In my case, I do both:

  1. I run Emacs on WSL 1 so that I can work with any of the files in my synced Dropbox.
  2. For longer development sessions, I rsync the relevant directories from NTFS to WSL 2 via WSL 1, because that’s still significantly faster than rsyncing directly from the 9p NTFS mounts on WSL 2 to WSL 2 local. I then work on them on the WSL 2 side, and rsync back at the end of the day.

In spite of the current cross-boundary filesystem performance issues, WSL 2 truly has fantastic potential.

I really hope that Microsoft are able to improve NTFS performance under WSL 2 up to at least WSL 1 levels. When that happens, WSL 2 will be a game changer for Linux devs on Windows.