Speed up WSL2 using a dedicated ext4 disk

Miguel MullerMiguel Muller
6 min read

Context

As a developer, I often work on projects that require good I/O performance — such as code compilation, dependency management, and running automated tests. On my personal laptop, I use Windows with WSL2 (Ubuntu) as my main development environment, and my laptop has two physical disks: one where Windows is installed, and another that I use to store my projects.

Initially, I kept my projects on this secondary drive, formatted as NTFS. However, I noticed performance bottlenecks when running intensive tasks via WSL2. This happens because WSL2 accesses files stored on NTFS volumes through a translation layer between operating systems, which directly impacts I/O performance — especially in operations with many files or complex builds. This is even documented by Microsoft itself, which recommends storing Linux files on native file systems such as ext4.

Set up a WSL development environment - File storage

For the fastest performance speed, store your files in the WSL file system if you are working on them with Linux tools in a Linux command line (Ubuntu, OpenSUSE, etc). If you're working in a Windows command line (PowerShell, Command Prompt) with Windows tools, store your files in the Windows file system. Files can be accessed across the operating systems, but it may significantly slow down performance.

Working across Windows and Linux file systems - File storage and performance across file systems

We recommend against working across operating systems with your files, unless you have a specific reason for doing so. For the fastest performance speed, store your files in the WSL file system if you are working in a Linux command line (Ubuntu, OpenSUSE, etc). If you're working in a Windows command line (PowerShell, Command Prompt), store your files in the Windows file system.

To solve this issue, I chose to use the second disk with the ext4 file system and mount it directly inside WSL2, ensuring native access to the file system and, consequently, better performance. After formatting as ext4, this disk will only be accessible inside WSL2. Windows does not natively support Linux file systems.

Below, I share the steps I followed to make this integration seamless, mounting the drive in WSL2 and ensuring it remains accessible even after system reboots.

Goal

Automatically mount a physical disk with an ext4 partition in WSL2, ensuring that:

  • The disk is accessible after Windows reboot.

  • The mount point is persistent and stable (e.g., /mnt/data).

  • The process is automated via PowerShell + /etc/fstab.

Backup and disk preparation:

  • Back up the data from the secondary drive.

  • Remove the partition from the secondary drive in Windows Disk Management.

  • Clean the drive using diskpart in Windows PowerShell.

    • You can prepare the drive using Linux from WSL, but for simplicity it's easier to do it from Windows.

Requirements

  • Windows 10 21H2 or later with WSL2 installed

  • A secondary physical disk

  • Familiarity with basic Linux/PowerShell commands

Step by step

1. Identify the physical disk in Windows

Use PowerShell to discover the device order number:

> Get-PhysicalDisk | Select-Object DeviceID, MediaType, Size, SerialNumber
# OR
> Get-PhysicalDisk | Select-Object DeviceID, FriendlyName, MediaType, Size, SerialNumber

You can also use diskpart to find the corresponding physical drive:

> diskpart
# AND
> list disk

2. Associate the disk with WSL

At this point, it is important to check the current disk structure in your WSL using lsblk:

To associate the PHYSICALDRIVE1 unit with WSL, use:

> wsl --mount \.\PHYSICALDRIVE1 --bare

--bare avoids automatically mounting any partition, giving you full control inside WSL.

After running the command to associate the drive, you'll notice it is visible in WSL. It will show up, but it is not yet mounted.

3. Associate the drive at system startup

To ensure that the disk is always accessible in WSL after reboots, create a PowerShell script — for example, associate-disc.ps1 — with the following content and save it on your main drive:

# Checks if the disk is already mounted
$mountedDisks = wsl --list --verbose | Select-String -Pattern "PHYSICALDRIVE1"

if (-Not $mountedDisks) {
    # Mounts the disk without trying to mount automatically
    wsl --mount \\.\PHYSICALDRIVE1 --bare
}

Set the script to run automatically at Windows startup.

  1. Open Windows Task Scheduler

    • Open with Win + R and type taskschd.msc
  2. Create a new task called Mount WSL Disk and check:

    • Run whether user is logged in or not

    • Do not store password

    • Run with highest privileges

  3. In the Triggers tab, create a new trigger:

    • Task should start At log on

    • Suggestion: delay task by 30 seconds

  4. In the Actions tab, link the script we created to be executed by PowerShell:

    • The action will be Start a program

    • Program/script will be powershell.exe

    • Arguments: -WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\{FOLDER}\associate-disc.ps1"

    • WindowStyle Hidden: hides the PowerShell window while the script runs.

    • ExecutionPolicy Bypass: temporarily ignores execution policy to allow the script to run.

4. Find the UUID of the secondary partition

Inside WSL, after running the script above, use:

> sudo blkid
# Example output:
# /dev/sdd1: UUID="c14b0e4a-f508-461a-b6e1-91d2bb6d683e" BLOCK_SIZE="4096" TYPE="ext4"

5. Configure /etc/fstab

Create the directory where the drive will be mounted:

> sudo mkdir -p /mnt/data

Add the following line to your /etc/fstab, specifying the UUID associated with the drive above:

UUID={UUID_HERE} /mnt/data ext4 defaults,nofail 0 0

6. Automatically mount on WSL startup

To activate the mount, just start WSL with the disk already mounted in Windows (via the .ps1 script). WSL will process fstab:

> sudo mount -a

After this, every time you log in to Windows, the drive will be automatically mounted in WSL2 and can be used normally in the /mnt/data directory.

Troubleshooting

Useful commands

  • blkid: Shows UUID, FS type, metadata

    • Purpose: Show the UUID, file system type (e.g.: ext4, swap), and other useful block device meta-information.

    • Useful for: configuring /etc/fstab, identifying volumes uniquely via UUID.

  • lsblk: Shows disk and mount hierarchy

    • Purpose: Show a hierarchical and organized view of block devices (disks and partitions), including mount points.

    • Useful for: seeing where partitions are mounted (/mnt/data, /, etc), which disks have partitions, and how they're related.

  • fdisk -l: Shows physical layout, sectors, partition type

    • Purpose: List detailed information from the partition table of disks.

    • Useful for: understanding the actual disk layout, number of sectors, partition type (Linux filesystem, EFI, etc), physical structure.

  • df -h: Shows total, used, and available space by file system

    • Purpose: Displays disk space usage by file system, with human-readable sizes.

    • Useful for: knowing how much total, used, and available space exists on each mount point.

Problem: UUID not found after reboot

This happens when PHYSICALDRIVE1 is not mounted before WSL starts. Solution:

Problem: empty mount point

If /mnt/data is empty:

  • Check if mount -a returned an error.

  • Use lsblk and sudo blkid to check if the partition is present.

Final considerations

This process ensures stable and reusable access to ext4 disks from WSL2, without relying on sharing via Windows. It's ideal for scenarios where you want to use a Linux disk as a persistent data directory in WSL.

If you have questions or suggestions for improvements, let me know!

0
Subscribe to my newsletter

Read articles from Miguel Muller directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Miguel Muller
Miguel Muller