WSL2 Optimization

The Only .wslconfig Guide You Need (Memory/CPU/Swap for Stability)

WSL2 is fantastic—until it randomly eats all your RAM, spins up the fans, or slows to a crawl during Docker builds or Node.js installs. The culprit is often WSL2’s default resource behavior: it can auto-expand memory up to most of your system, it uses a swap file you might not control, and it doesn’t always release memory back promptly. The good news: you can fix this reliably with one file on Windows, the global .wslconfig. In this article, The Only .wslconfig Guide You Need (Memory/CPU/Swap for Stability), you’ll learn exactly how to configure WSL2 memory, CPU, and swap for speed and stability. We’ll cover realistic defaults, explain every option, show Docker best practices, and walk through common fixes.

You’ll leave with a clean template and the confidence that your WSL2 environment won’t disrupt your workflow again.

Overview

WSL2 runs a lightweight virtual machine that hosts your Linux distributions. By default, it aggressively uses available system resources, and while that can be great for performance, it can also lead to:

  • High Vmmem usage in Task Manager (WSL2’s VM host process)
  • System-wide sluggishness on Windows
  • Unpredictable Docker Desktop performance or OOM kills
  • Slow file I/O when working from Windows-mounted paths (/mnt/c)
  • Bloated ext4.vhdx files consuming disk space

The fix is to create a global .wslconfig file in your Windows user profile to set caps for memory, CPU, and swap, and to enable a few stability features. This guide explains what to set, why, and how to verify it’s working.

Quick Reference Table

Command Purpose Example Output
wsl –status Show WSL status and defaults Default Distribution: Ubuntu; Default Version: 2; Kernel version: 5.15.x
wsl –version Show WSL (Store) version and kernel WSL version: 2.2.5.0; Kernel version: 5.15.133.1
wsl –list –verbose List distros with version Ubuntu-22.04 Running 2; docker-desktop-data Stopped 2
wsl –shutdown Apply .wslconfig changes by stopping all VMs (No output)
notepad %UserProfile%.wslconfig Create/edit global .wslconfig Opens Notepad
cat /proc/meminfo (inside WSL) Verify memory cap inside WSL MemTotal: 8123456 kB
docker info (inside WSL) Verify Docker sees the memory cap Total Memory: 7.8GiB
wsl –update Update WSL components Installing: Windows Subsystem for Linux… Done
ipconfig /flushdns Clear Windows DNS cache (network fix) Successfully flushed the DNS Resolver Cache.

Key Concepts & Prerequisites

  • Windows requirements
    • Windows 10 2004+ or Windows 11; for the newest features (mirrored networking and networking flags), Windows 11 or the latest WSL from the Store is recommended.
    • Administrator rights for some troubleshooting tasks (e.g., optional disk compaction).
  • WSL2 version
    • Use wsl –version. Prefer the latest Store version for bug fixes and networking improvements.
  • Editing files
    • You’ll edit Windows-side files (like %UserProfile%.wslconfig) with a Windows editor (Notepad/VS Code) and Linux-side files (like /etc/wsl.conf) with a Linux editor (nano/vim).
  • Disk layout basics
    • Each WSL2 distro stores its data in an ext4.vhdx file. It grows with usage and doesn’t shrink automatically.
  • Docker Desktop
    • If you use Docker with WSL2, its resource usage is governed by .wslconfig. Make sure Docker Desktop uses the WSL2 backend and integrates with your distro.

Step-by-Step Guide

  1. Check your WSL installation and versions
  • Run these in Windows Terminal (PowerShell or CMD):

    wsl –status
    wsl –version
    wsl –list –verbose

  • Interpretation:

    • You should see Default Version: 2 and your distro(s) running version 2.
    • The WSL version line (from the Store) should be recent. If not, run:
      wsl –update
  1. Create or edit the global .wslconfig
  • Open or create the file:

    notepad %UserProfile%.wslconfig

  • This file applies to all WSL2 distros and Docker Desktop’s Linux backend.

  1. Start with a proven baseline .wslconfig
See also  Fix DNS/Network Issues Between Windows and WSL2 (Reliable Methods)

Paste this template and adjust the numbers to your machine:

[wsl2]

Cap memory so WSL2/Docker never starve Windows

memory=8GB # Pick 50–66% of your RAM as a starting point
processors=6 # Leave 2–4 cores for Windows on multicore systems

Swap for stability (avoid OOM kills under load)

swap=16GB # 1–2x the memory cap is common; 0 disables swap
swapfile=C:\wsl-swap.vhdx # Put on a fast SSD, escape backslashes

Make memory reclaim more effective

pageReporting=true # Allows Windows to reclaim unused pages from WSL

VM lifecycle

vmIdleTimeout=300000 # 5 minutes; 0 = never auto-shutdown

Networking (Windows 11 + recent WSL)

networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true

Useful toggles

localhostForwarding=true
nestedVirtualization=false
guiApplications=true # Set false if you don’t use WSLg

  1. Choose the right memory and CPU values
  • Memory cap (memory=)

    • For 8 GB RAM host: 4–5GB
    • For 16 GB RAM: 6–10GB
    • For 32 GB RAM: 12–20GB
    • If you run large Docker stacks or databases, lean higher. If your Windows desktop feels sluggish, lower it a bit.
    • This is a cap, not a reservation—WSL2 will not consume it unless needed.
  • CPU cap (processors=)

    • Defaults to all cores. Cap it to give Windows headroom.
    • Example: On a 12-core CPU, allocate 6–10 for WSL depending on workload.
  1. Configure swap correctly
  • swap= sets the total swap size. swapfile= points to a Windows-side file that WSL uses as swap.

  • Recommendations:

    • Start with swap equal to 1x memory cap, up to 16–32GB for heavy build/DB workloads.
    • Avoid swap=0 unless you know your workloads won’t burst; swap significantly reduces OOM-related crashes.
    • Place the swapfile on a fast SSD (e.g., C:) and ensure there’s free space.
  • Example:

    • If memory=8GB, set swap=8–16GB. If memory=12GB, set swap=12–24GB.
  1. Apply the configuration
  • Save .wslconfig in Notepad.

  • Run:

    wsl –shutdown

  • Start WSL again by opening your distro or a WSL terminal. Verify caps:

    cat /proc/meminfo | grep MemTotal
    nproc

  • Check Task Manager’s Vmmem process under Details while stressing WSL; it should not exceed your cap.

  1. Docker Desktop considerations
  • Ensure Docker Desktop uses the WSL2 backend and integrates with your distro (Settings > Resources > WSL Integration).

  • Docker now respects WSL’s caps; the old resource sliders are ignored when using WSL2.

  • Verify in WSL:

    docker info | grep -i “total memory”

  • For heavy Compose stacks, set memory and swap high enough to avoid thrashing. You can still set per-container resource limits in Compose, but the global ceiling comes from .wslconfig.

  1. Optional: Networking stability and VPN compatibility
  • If you hit connectivity problems, try switching modes:

    • Mirrored networking (Windows 11 + recent WSL) is more seamless (same IP as Windows, better localhost).
    • NAT mode can be more compatible with some VPNs.
  • To force NAT:

    [wsl2]
    networkingMode=nat
    localhostForwarding=true

  • Then:

    wsl –shutdown

  1. Verify performance improvements
  • Try a typical workload (npm ci, docker compose up, or a database import).
  • Check CPU/RAM usage in Task Manager. You should see predictable caps and fewer spikes.
  • If Windows feels sluggish, lower memory= or processors= slightly.
See also  Run Databases in WSL2 (Postgres/MySQL/Mongo) Without Performance Regret

Troubleshooting

  • DNS not working inside WSL

    • Symptom: apt/pnpm/npm/curl cannot resolve hosts.

    • Fix 1 (modern WSL): Ensure networkingMode=mirrored and dnsTunneling=true in .wslconfig, then:
      wsl –shutdown

    • Fix 2 (manual resolv.conf):

      1. Inside WSL, edit /etc/wsl.conf:

        sudo nano /etc/wsl.conf
        [network]
        generateResolvConf = false

      2. Reset resolv.conf:

        sudo rm /etc/resolv.conf
        echo “nameserver 1.1.1.1” | sudo tee /etc/resolv.conf
        echo “nameserver 8.8.8.8” | sudo tee -a /etc/resolv.conf

      3. Restart WSL:

        wsl –shutdown

    • Optional on Windows:

      ipconfig /flushdns
      netsh winsock reset

  • git is slow or CPU spikes during status/checkout

    • Root cause: Accessing repos in /mnt/c (Windows filesystem) is much slower than Linux filesystem.

    • Fix:

      • Move your repo to the Linux filesystem (e.g., ~/code/myrepo). Access it from Windows via \wsl$\YourDistro\home\you\code\myrepo.

      • Enable fsmonitor (requires recent Git):

        git config –global core.fsmonitor true

      • Avoid antivirus scanning your \wsl$ paths. Optionally add a Defender exclusion for your \wsl$ distro path (security trade-off).

  • Disk space bloating (ext4.vhdx keeps growing)

    • Symptom: Your distro’s ext4.vhdx becomes very large and does not shrink after deleting files.

    • Option A: Export/import (works everywhere, slower, re-creates the distro)

      • From Windows:

        wsl –export Ubuntu D:\Backups\ubuntu.tar
        wsl –unregister Ubuntu
        wsl –import Ubuntu D:\WSL\Ubuntu D:\Backups\ubuntu.tar –version 2

      • You’ll need to reconnect Docker/VS Code integrations.

    • Option B: Hyper-V Optimize-VHD (faster, requires Hyper-V PowerShell)

      1. Inside WSL, write zeros to free space:

        dd if=/dev/zero of=~/zero.fill bs=1M || true
        sync
        rm ~/zero.fill

      2. Shutdown WSL:

        wsl –shutdown

      3. In an elevated PowerShell (requires Hyper-V PowerShell module):

        Optimize-VHD -Path “C:\Users\YOU\AppData\Local\Packages\\LocalState\ext4.vhdx” -Mode Full

  • File I/O is slow for Node.js/webpack/PNPM/NPM

    • Fixes:
      • Keep node_modules and repo in Linux filesystem.
      • For Docker, prefer named volumes or bind-mount from \wsl$ (Linux path) rather than C:.
      • Consider reducing file watchers (e.g., CHOKIDAR_USEPOLLING=false for some Node tools).
      • Use PNPM store inside Linux (see Project Example below).
  • Vmmem high CPU or RAM after closing terminals

    • Run:

      wsl –shutdown

    • Consider setting vmIdleTimeout to a few minutes to auto-stop WSL when idle.

    • Set pageReporting=true to improve Windows memory reclamation from WSL.

Optimization & Best Practices

  • Memory/CPU tuning

    • Use a memory cap that leaves Windows comfortable: 50–66% of total RAM is a safe starting point.
    • Cap processors to avoid saturating Windows background tasks. Leave at least 2–4 cores for the host OS.
    • Avoid swap=0 unless you never push memory limits. Swap stabilizes bursty workloads.
  • Filesystem placement

    • Linux filesystem (\wsl$ share) is much faster for tools like npm, yarn, pnpm, git, and compilers. Keep repos and databases there.
    • If you must work in /mnt/c, expect slower metadata operations. Keep node_modules on Linux when possible.
  • Docker with WSL2

    • Enable WSL2 integration in Docker Desktop; don’t use legacy Hyper-V mode.
    • Use named volumes or Linux-path bind mounts. Avoid bind mounts to C:\ for hot code paths.
    • .wslconfig is the global resource cap; still set per-service limits in Compose if needed.
  • Keep WSL updated

    • wsl –update and ensure Windows Updates are current for networking and filesystem improvements.
    • Occasionally reboot Windows to clear long-lived VMs and networking state.
  • Antivirus/indexing

    • Real-time scanning of \wsl$ can hurt performance. If allowed in your environment, add targeted exclusions for heavy-use paths.
  • Stability flags that help

    • pageReporting=true: Helps Windows reclaim memory WSL doesn’t need.
    • vmIdleTimeout: Automatically stops idle VMs.
    • networkingMode=mirrored with dnsTunneling/firewall/autoProxy: Generally smoother networking on Windows 11 with the Store WSL.
See also  Speed Up File I/O: Where to Keep Code—Linux vs Windows Paths

Project-Based Example: Fast Node.js Monorepo + PostgreSQL on WSL2

Goal: Speed up installs/builds and make local DB reliable without starving Windows.

  1. Set .wslconfig for a 16 GB laptop

[wsl2]
memory=10GB
processors=8
swap=16GB
swapfile=C:\wsl-swap.vhdx
pageReporting=true
vmIdleTimeout=300000
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
guiApplications=true

Apply it:

wsl –shutdown

  1. Put your project in the Linux filesystem
  • In WSL:

    mkdir -p ~/code
    cd ~/code
    git clone git@github.com:org/monorepo.git
    cd monorepo

  • Open from Windows via \wsl$\Ubuntu\home\you\code\monorepo in VS Code (or use “code .” with the Remote – WSL extension).

  1. Optimize Node.js package manager behavior
  • PNPM (recommended for speed/space):

    corepack enable
    pnpm config set store-dir ~/.pnpm-store
    pnpm config set prefer-frozen-lockfile true

  • NPM:

    npm config set cache ~/.npm-cache –global
    npm ci

  • Yarn:

    yarn config set cache-folder ~/.yarn-cache

  • Ensure caches live in the Linux filesystem (your home directory).

  • Optional Git optimizations:

    git config –global core.fsmonitor true
    git config –global fetch.writeCommitGraph true
    git config –global gc.writeCommitGraph true
    git config –global feature.manyFiles true

  1. Run PostgreSQL via Docker with Linux-native volumes
  • docker-compose.yml snippet:

    services:
    db:
    image: postgres:16
    environment:

    • POSTGRES_PASSWORD=dev
      ports:
    • “5432:5432”
      volumes:
    • pgdata:/var/lib/postgresql/data

    volumes:
    pgdata:

  • Start it from WSL:

    docker compose up -d
    docker exec -it $(docker ps -qf name=db) psql -U postgres -c “SELECT version();”

  • Check Docker’s memory view:

    docker info | grep -i “total memory”

  1. Validate results
  • Run full workspace install/build:

    pnpm -w install
    pnpm -w build

  • Observe:

    • Faster installs/builds than working on /mnt/c
    • Consistent resource usage; Task Manager’s Vmmem stays under ~10GB
    • No Windows-wide slowdowns during compiles or DB operations
  • If Windows is still sluggish:

    • Lower memory to 8GB or processors to 6; wsl –shutdown and try again.

Conclusion

With a simple, well-tuned .wslconfig, you can transform WSL2 from “resource hog” to a predictable, high-performance development environment. Cap memory and CPUs, size your swap for stability, keep projects on the Linux filesystem, and let Docker operate with Linux-native volumes. The result: faster package installs and builds, more reliable databases, and a Windows desktop that stays responsive. WSL2 can be fast and rock-solid—it just needs a few thoughtful settings.

FAQ

Where do I put the .wslconfig file?

In your Windows user profile: %UserProfile%.wslconfig. It applies to all WSL2 distros and Docker’s WSL backend. Edit it with Notepad or VS Code, then run wsl –shutdown to apply.

How do I know my memory and CPU limits are active?

Inside WSL, check cat /proc/meminfo and nproc. In Windows Task Manager, Vmmem won’t exceed the memory cap under load. docker info will also show the capped Total Memory.

What’s a good starting point for memory, CPUs, and swap?

  • 8 GB RAM: memory=4–5GB, processors=4, swap=8GB
  • 16 GB RAM: memory=6–10GB, processors=6–10, swap=8–16GB
  • 32 GB RAM: memory=12–20GB, processors=8–16, swap=16–32GB
    Adjust up for heavy Docker/DB use; down if Windows feels sluggish.

Is swap required? Is disabling swap faster?

Swap stabilizes bursty workloads and reduces OOM kills. Disabling swap (swap=0) can be risky for compiles or Node installs. If you do disable it, ensure your memory cap is high enough and watch for OOM errors.

My VPN breaks WSL networking. What should I try?

Switch networking modes. For many VPNs, NAT mode helps:
[wsl2]
networkingMode=nat
localhostForwarding=true
Then run wsl –shutdown. If DNS fails, either enable dnsTunneling=true in mirrored mode or use a static resolv.conf as shown in Troubleshooting.

Happy building! With the right .wslconfig, WSL2 becomes a fast, stable, and reliable companion for your daily development work.

About the author

Jonathan Dudamel

Jonathan Dudamel

I'm Jonathan Dudamel, an experienced IT specialist and network engineer passionate about all things Windows. I have deep expertise in Microsoft project management, virtualization (VMware ESXi and Hyper-V), and Microsoft’s hybrid platform. I'm also skilled with Microsoft O365, Azure ADDS, and Windows Server environments from 2003 through 2022.

My strengths include Microsoft network infrastructure, VMware platforms, CMMS, ERP systems, and server administration (2016/2022).