# Speed up WSL2 using a dedicated ext4 disk

# 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**](https://learn.microsoft.com/en-us/windows/wsl/setup/environment?source=recommendations#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**](https://learn.microsoft.com/en-us/windows/wsl/filesystems#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:

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703685096/a51a0980-fe62-42be-8a9b-0262f17046c7.png align="left")

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

```powershell
> diskpart
# AND
> list disk
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703702105/8bbe072f-6e17-4279-a037-fb6e0a8aecda.png align="left")

### **2\. Associate the disk with WSL**

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748714365410/9aa99105-dd92-48d5-aa9f-73bfc8e22a0a.png align="center")

To associate the `PHYSICALDRIVE1` unit with WSL, use:

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

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703752497/75569e65-02c4-4130-9070-96eb3c16839a.png align="left")

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.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703794270/1023614d-d0ea-4203-8ea1-095a628e05ec.png align="left")

### **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`](http://associate-disc.ps) — with the following content and save it on your main drive:

```powershell
# 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
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703821363/526e8f84-f69c-46e6-989d-9e9a31778005.png align="left")

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
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703839577/e39d63ec-3e7d-4f69-baf2-c1a995b11ce8.png align="left")
        
3. **In the Triggers tab, create a new trigger:**
    
    * Task should start `At log on`
        
    * Suggestion: delay task by 30 seconds
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703874911/344e4c4a-8285-48b4-9d0b-30a7ffa037cc.png align="left")
        
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"`
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703910132/56cad057-b175-41e4-bf80-840aed118147.png align="left")
        
    * `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:

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703944987/f714713f-7ff0-4ba2-97ec-0fab9288f7b4.png align="left")

### 5\. Configure `/etc/fstab`

Create the directory where the drive will be mounted:

```bash
> sudo mkdir -p /mnt/data
```

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

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1748703981273/2528d412-5815-4e84-86d7-6f9b2ca72fd2.png align="left")

### 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`:

```bash
> 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:

* Make sure the [`mount-ext4.ps`](http://mount-ext4.ps) script runs before opening WSL.
    

### 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!
