# Notes on WSL Tuning

**Date:** 2024-02-19  
**Author:** Kees C. Bakker  
**Categories:** Installation Notes, PowerShell, Windows  
**Tags:** WSL  
**Original:** https://keestalkstech.com/notes-on-wsl-tuning/

![Notes on WSL Tuning](https://keestalkstech.com/wp-content/uploads/2024/02/martin-wettstein-fgG7Bg0w4NI-unsplash.jpg)

---

Here I'll store my notes on WSL tuning. I mainly use WSL to do [Dev Containers](https://keestalkstech.com/tag/dev-containers/), so I need it to run as smooth as possible. My main problems include: memory and disk size. Let's see what we can do to address the problem.

## How big are my virtual hard disks?

The following script will show the name of the distro, the size and the path of the virtual hard disks:

```
Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss\ | ForEach-Object {

  $psPath = (Get-ItemProperty -Path $_.PsPath)
  $distro = $psPath.DistributionName
  $vhdxPath = $psPath.BasePath + "\ext4.vhdx"
  $vhdxSize = (Get-Item $vhdxPath).Length / 1GB

  [PSCustomObject]@{
    DistributionName = $distro
    SizeGB = [math]::Round($vhdxSize, 2).ToString("0.00")
    VHDXPath = $vhdxPath.Replace("\\?\", "")
  }

} | Format-Table -Wrap -Property `
  DistributionName, `
  @{Name='SizeGB'; Expression={$_.SizeGB}; Alignment='right'}, `
  VHDXPath
```

Now you know what might eat up your hard disk.

## Manually shrinking the hard disks

The following script will prune your docker containers and image, iterate your virtual hard disks and perform a shrink:

```
# make sure we're admin
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
        $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
        Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
        Exit
    }
}

Write-Host
Write-Host "Pruning containers" -ForegroundColor Blue
docker container prune --force

Write-Host
Write-Host "Pruning images" -ForegroundColor Blue
docker image prune --all --force

wsl --shutdown

Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss\ | ForEach-Object {
  $psPath = (Get-ItemProperty -Path $_.PsPath)
  $distro = $psPath.DistributionName
  $vhdxPath = $psPath.BasePath.Replace("\\?\", "") + "\ext4.vhdx"
  $vhdxSize = [Math]::Round((Get-Item $vhdxPath).Length / 1GB, 2).ToString("0.00")

  Write-Host
  Write-Host "Shrinking distro: " -NoNewline -ForegroundColor Blue
  Write-Host $distro -ForegroundColor Yellow
  Write-Host " - before: $vhdxSize"

  try {
    Optimize-VHD -Path $vhdxPath -Mode Full -ErrorAction Stop
    $vhdxSize = [Math]::Round((Get-Item $vhdxPath).Length / 1GB, 2).ToString("0.00")
    Write-Host " - after:  $vhdxSize" -ForegroundColor Green
  } catch {
    if ($_.Exception.Message -match "Virtual hard disk files must be uncompressed and unencrypted and must not be sparse.") {
      Write-Host " - cannot shrink disk as it is already sparse" -ForegroundColor Red
    } else {
      Write-Error "Error: $($_.Exception.Message)"
    exit
    }
  }
}

Write-Host
Read-Host -Prompt "Press Enter to exit"
```

But you might want to go one further and make those disks sparse!

## Stop the bleeding

We can stop the bleeding by configuring WSL2 differently. The [September 2023 update](https://devblogs.microsoft.com/commandline/windows-subsystem-for-linux-september-2023-update/) includes some great new features:

- Automatic memory reclaim.
- Sparse virtual hard disks, which will give the disk space back.
- Better networking.

### Upgrade to the latest release

First you'll need to upgrade to the store version, then to the pre-release version:

```
wsl --shutdown
wsl --update
wsl --update --pre-release
```

### WSL Config

Next, you might want to now how many (logical) processors and memory you have:

```
$logicalProcessors = (Get-WmiObject -Class Win32_ComputerSystem).NumberOfLogicalProcessors
$totalMemoryGB = [Math]::Round((Get-WmiObject -Class Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)
$output = "Number of Logical Processors: $logicalProcessors"
$output += "`nTotal Memory (GB):            $totalMemoryGB"
Write-Output "$output"
```

Based on these settings you might want to tune your WSL config. I open it by doing `code (Join-Path (Resolve-Path ~) .wslconfig)` in a terminal and adding the following to the file:

```
[wsl2]
memory=10GB
processors=14
guiApplications=false

[experimental]
autoMemoryReclaim=gradual
sparseVhd=true
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
```

I configured my **memory** to be ~2/3 of my machine. I keep 2 cores back for the **processor** config.

Notice how I disabled Linux GUI applications, as it keeps messing up my dev containers with the error: *Error response from daemon: invalid mount config for type "bind": bind source path does not exist: \wsl.localhost\Ubuntu\mnt\wslg\runtime-dir\wayland-0*. Adding `guiApplications=false` will fix that.

### Settings all your WSL distros to sparse

Now that we've updated and activated our sparse disk, we can apply them to all disks:

```
wsl --shutdown

Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss\ | ForEach-Object {

  $distro = (Get-ItemProperty -Path $_.PsPath).DistributionName

  Write-Host
  Write-Host "Changing distro: " -NoNewline -ForegroundColor Blue
  Write-Host $distro -ForegroundColor Yellow

  wsl --manage $distro --set-sparse true
}
```

## Changelog

- 2024-04-03: Make sure we disable Wayland / Linux GUI apps to prevent errors on our Dev Containers.
- 2024-02-20: Fixed the opening of the `~/.wslconfig` if it does not exist.
- 2024-02-19: Initial article.
