When this question was first written, neither WSL2 nor WSLg had been released, so the answer today is certainly different than it was a few years ago. Some of that info has been updated in answers here, but I feel there's a lot missing in other answers here around actual "limitations".
I'm a fairly big WSL fan, but I'll be the first to acknowledge that there are quite a few limitations when it comes to WSL. Fortunately, most of these have workarounds, but they do catch most new users off guard.
To start with, let me just lay out some "differences" between Ubuntu on WSL and a traditional Ubuntu installation on a VM or physical machine. I'll reference some of these in the "limitations" section below:
WSL1 runs as a "syscall translation layer" that attempts to translate Linux kernel API's into those of the Windows kernel.
Ubuntu running in WSL2 acts more like a container. It is running under a real Linux kernel in a managed virtual machine (that you can't access). Ubuntu is running inside a namespace in that VM. It is not, itself, directly running in a VM.
WSL has its own init system. Its main job (other than some "normal" Linux init tasks) is to set up the interoperability between Linux and Windows. For instance, it:
- makes the Windows network available to Ubuntu
- adds the Windows path to the environment
- mounts Windows drives into Ubuntu
That init runs as PID 1 inside the Ubuntu WSL instance/namespace/container, unless you enable Systemd support, in which case Systemd becomes PID 1.
Starting WSL is not like booting a virtual or physical machine. Many of the tasks that Ubuntu would normally (typically through Systemd) do during boot are either not needed for WSL or are actually harmful to its normal operation.
There is no concept of a "login" when starting WSL. WSL detects the default user and automatically starts the shell defined for that user in /etc/passwd
. No password is requested or needed.
Limitations of WSL
With that in mind, here are some limitations that I can think of:
init/Systemd:
Out of the box, WSL still does not have Systemd enabled, but it is available, and now works on both Windows 10 and Windows 11. Many docs, blog posts, etc. that you come across for various tasks (e.g. installing Docker) will assume that Systemd is enabled, so you'll need to either make sure that it is or learn how to adapt without it.
There were quite a few other Systemd-related limitations in this section, but they have been removed based on recent WSL improvements.
Access to physical hardware: On WSL, you will have limited access to hardware:
Serial ports: WSL1 has access to serial ports at some level, but only as far as the syscall implementations go. That said, it's possible to run some software on WSL1 that utilizes the serial ports that is not possible on WSL2.
Physical drives: Older versions of WSL lacked the ability to access physical drives, but recent WSL releases now do include the ability to mount physical drives, as long as they aren't in use by Windows.
However, USB mass storage devices are not directly supported unless you use a special kernel.
- Graphics: This used to be more of a limitation, but WSL 1.0.0 added support for GUI applications with WSLg (for both Windows 10 and 11). This support is through Wayland/XWayland/Weston running with an RDP backend. Of course, there still isn't any direct access from X to the physical hardware, so there are some things that don't work just like their "pure" Ubuntu equivalent.
One of the most common is in running desktop environments. You'll find several question and answers here on Ask Ubuntu around this topic.
GPU: Under recent Windows 10 versions, some GPU Compute tasks are available using a passthrough library and the Windows GPU drivers.
Under Windows 11, some additional GPU Compute tasks have been added.
USB: USB devices are not directly accessible. However, under WSL2 (both in Windows 10 and 11), they can be shared from Windows using USB/IP and then attached in Ubuntu.
Note, though, that the stock WSL2 kernel does not include most device drivers for USB devices. For instance, even the basic media capture (i.e. camera) drivers are not included. However, you can build your own kernel for WSL2 and include the necessary drivers. However, note that currently, I (and others) have not succeeded in capturing video from a USB camera in WSL. See this question on Stack Overflow for the progress-to-date.
Ubuntu boot device: The primary boot virtual disk/partition for Ubuntu in WSL must be formatted ext4. Although the WSL2 kernel supports additional filesystems such as btrfs, they can only be used for secondary partitions.
Tasks that rely on authentication/login: Due to (6) above, certain tasks that rely on authentication will behave differently on WSL. For instance, normally you would edit /etc/security/limits.conf
to raise the limits (e.g. number of open files, priority/nice, etc.) for a user. However, this is a file that is handled by PAM (the "pluggable authentication module") during user login. Without an authenticated login, this file is never processed. See workaround in this answer if you come across this.
Networking: While this might belong under the "hardware" section, it probably deserves its own callout here. WSL2's network currently runs under a virtual switch inside Hyper-V, and that switch is NAT'd from the rest of the network. This means that you cannot easily access network services in WSL2 from other devices (computers, phones, etc.) on the local network without additional effort.
The easiest workaround is to use WSL1 for this when possible. There are multiple other workarounds as well.
VPNs: Likewise, when connecting to certain VPN's which disable local traffic, WSL2 will lose networking, since it is "local" (but not localhost) network traffic.
Pen-testing: Some penetration testing tasks simply won't work under with WSL1 (because of the limited syscall translations) nor WSL2 (because hardware is virtualized). Two areas stand out here:
Direct access to the wifi interface is not available (only a virtual ethernet device), so WLAN password cracking techniques will not work. As a workaround, it should be possible to install a secondary USB WiFi dongle, pass it through via USB/IP as discussed above, and use it inside WSL2. Note that you will need to build your own kernel with the appropriate drivers for the network dongle.
Because WSL2 is on a separate layer 2 network than your Windows host (and the rest of your network), it won't be possible to do any layer 2 scanning. The above USB/IP workaround should work for this as well.
Performance: In general, performance under WSL2 is pretty good. However, there are a few caveats:
WSL1: WSL1 has slightly reduced performance on its "pseudo-ext4/overlay" filesystem. However, WSL2 achieves near-native performance on ext4 filesystems.
WSL2: WSL2 takes a huge performance hit when accessing files on Windows drives, especially multiple, small files. Checking out the WSL2 kernel on an NTFS drive takes over 10 minutes (but ~30 seconds otherwise). It is highly recommended that you keep project files on the ext4 filesystem or use WSL1 when accessing Windows drives.
I keep a WSL1 instance around primarily for the purpose of working with Windows drives when needed.
I'm sure I'll remember some more (or perhaps someone will point them out in the comments), and I'll add them in if needed.
Again, with the workarounds mentioned, most of these are not serious blockers for most WSL users. However, they are the source of many questions that I've answered across the Stack Exchange sites.