
Optimizing WSL2 for Claude Code: Complete Performance Tuning Guide (2026)
I may be the only person left who actually chooses to develop on Windows in 2026. Every conference talk, every dev influencer, every "what's in my setup" post -- it's all Mac or Linux. And honestly, I get it. I'm a Windows guy at heart, but even I will admit that PowerShell is a cruel joke you shouldn't play on your friends.
Here's the thing though: WSL gives you a real Linux kernel, a real ext4 filesystem, and a real bash shell -- all running inside Windows. You get the Linux development experience without giving up the Windows desktop you've spent decades customizing. For someone like me who has 30 years of muscle memory in Windows and zero interest in learning how to right-click on a Mac, WSL2 is the best of both worlds.
So when I set up Claude Code -- Anthropic's agentic coding assistant for the terminal -- the question wasn't whether to use WSL2. It was how to squeeze every last drop of performance out of it. We recently audited and tuned a WSL2 environment on a workstation with 64 GB of RAM and a 20-thread Intel i7-13700. This post documents every optimization we made, the benchmarks that motivated them, and the known issues you should watch out for.
Key Findings
- WSL2 with ext4 is ~9x faster than accessing Windows files via the 9P bridge -- the single biggest performance win, and it costs nothing
- Allocating 50-75% of system RAM to WSL2 eliminates out-of-memory kills during large project indexing
- Mirrored networking mode fixes localhost connectivity between Windows and WSL2 (but breaks Docker -- see warning below)
- Increasing inotify watches to 524,288 prevents file-watching failures in projects with 10,000+ files
- Sparse VHD mode recovers unused disk space automatically, though manual compaction may still be needed
- WSL is now open-source (Build 2025), and WSL 2.7.0 with kernel 6.6.114.1 is the latest release
- GPU passthrough works for CUDA/AI workloads without installing Linux drivers
- 8 documented Claude Code issues have WSL-specific fixes covered in this guide (plus a maintenance schedule to keep everything current)
Table of Contents
- Why WSL2 for Claude Code
- System Requirements
- Installation
- Filesystem Performance: The Single Biggest Win
- Configuring .wslconfig for Maximum Performance
- Configuring /etc/wsl.conf
- Shell Environment Setup
- Networking and DNS Optimization
- System Limits and File Watching
- VS Code Integration
- GPU Acceleration for AI/ML Workloads
- Security: API Keys and Environment Variables
- MCP Servers and Path Translation
- Disk Space Management
- Keeping Your WSL Environment Updated
- Known Issues and Workarounds
- FAQ
- Checklist
- Sources
Why WSL2 for Claude Code
Claude Code supports multiple Windows installation modes:
| Mode | Sandboxing | Filesystem Perf | Linux Toolchain | Setup Effort |
|---|---|---|---|---|
| Native Windows (Git Bash / PowerShell) | No | Native NTFS | No | Low |
| WSL 1 | No | Good cross-OS, slower native | Yes | Medium |
| WSL 2 | Yes | Fast native Linux | Yes | Medium |
Note: Windows also has native installers -- PowerShell (irm https://claude.ai/install.ps1 | iex) and CMD (curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd). For simple use cases, those are the easiest path. But if you care about sandboxing, filesystem performance, and a full Linux toolchain, WSL2 is the better option.
Update (2025): Microsoft open-sourced WSL at Build 2025 under the MIT license. The wsl.exe, wslg.exe, wslservice.exe, and Linux-side networking daemons are all on GitHub now. Only the WSL1 kernel driver (lxcore.sys) and the \\wsl.localhost filesystem redirector remain closed. WSL 2.7.0 (December 2025) is the latest release, running kernel 6.6.114.1.
WSL2 is the recommended path for serious development because:
- Sandboxing support: Claude Code can use bubblewrap and socat to sandbox Bash tool execution, isolating file system and network access. This only works on WSL2, not WSL1 or native Windows. (Source)
- Native Linux filesystem: WSL2 runs a real Linux kernel (6.6.114.1 as of WSL 2.7.0) with an ext4 filesystem. As we will show below, this is roughly 9x faster than accessing Windows drives.
- Full Linux toolchain: ripgrep, git, build tools, and language runtimes all run natively without translation.
- Better networking options: WSL2 supports mirrored networking and DNS tunneling, which improve compatibility with corporate VPNs and proxies.
System Requirements
Based on the official Claude Code documentation:
| Requirement | Minimum | Recommended (Our Setup) |
|---|---|---|
| OS | Windows 10 1903+ (WSL2 requires build 18362+) | Windows 11 (latest) |
| RAM | 4 GB | 64 GB |
| WSL distro | Ubuntu 20.04+ / Debian 10+ | Ubuntu 24.04 LTS |
| Node.js | 18+ (npm install only) | v24.13.0 |
| Shell | Bash or Zsh | Bash |
| Network | Internet connection | Stable broadband |
For the native installer (recommended), Node.js is no longer a hard requirement -- Claude Code ships its own runtime. Node.js is only needed if you install via the deprecated npm method.
Installation
The recommended installation method inside WSL is the native installer:
# Inside your WSL2 terminal
curl -fsSL https://claude.ai/install.sh | bash
This installs a self-contained binary to ~/.local/bin/claude and sets up automatic background updates. If you prefer the stable release channel over the latest, append -s stable:
curl -fsSL https://claude.ai/install.sh | bash -s stable
Other installation methods are also available (Homebrew with brew install --cask claude-code, WinGet with winget install Anthropic.ClaudeCode) but the curl installer is recommended for WSL because it includes automatic updates.
If you have an existing npm installation, migrate it:
claude install
After installation, verify your setup:
claude doctor
Common Installation Pitfalls on WSL
OS/platform detection errors: WSL may pick up the Windows npm instead of the Linux one. Fix:
npm config set os linux
npm install -g @anthropic-ai/claude-code --force --no-os-check
Node not found: If which node points to /mnt/c/..., your WSL is using the Windows Node. Install Node natively in WSL:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.nvm/nvm.sh
nvm install --lts
nvm version conflicts: WSL imports the Windows PATH by default, which can cause the Windows nvm/npm to shadow the Linux one. Ensure your .bashrc loads nvm properly:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
Sandbox dependencies: To enable /sandbox mode, install:
sudo apt-get install bubblewrap socat
Filesystem Performance: The Single Biggest Win
This is the most impactful optimization you can make, and it costs nothing.
Our Benchmark Results
We benchmarked sequential write throughput on the same machine using dd with bs=1M count=1024 conv=fdatasync oflag=direct (which measures actual disk throughput, not page cache):
| Filesystem | Path | Throughput | Relative |
|---|---|---|---|
| Linux ext4 (WSL2 native) | ~/projects | ~1.0 GB/s | 1.0x |
| Windows NTFS via 9P mount | /mnt/c/Users/.../projects | ~110 MB/s | ~0.11x |
The Linux filesystem is approximately 9x faster than accessing Windows drives from WSL2. This is because /mnt/c uses the 9P protocol to bridge between the Linux kernel and the Windows NTFS driver, adding significant overhead on every I/O operation.
Note: Cached writes (hitting the Linux page cache before flushing to the virtual disk) can show much higher numbers -- we've seen 2.9 GB/s in cached benchmarks. But even the conservative direct-I/O numbers show a dramatic difference. The ratio matters more than the absolute numbers, and for real-world Claude Code operations (ripgrep searches, git operations, builds, file writes), the ext4 advantage is consistent and significant.
For broader context: Phoronix benchmarked WSL2 on Windows 11 25H2 (September 2025) and found WSL2 delivers approximately 87% of bare-metal Linux performance across 50+ benchmarks. CPU-bound tasks show 10-15% overhead; I/O-bound tasks up to 20%. Even on native ext4, WSL2 still carries some virtualization overhead -- but it's far better than crossing the 9P bridge.
What to Do
Move your projects from Windows drives into the Linux filesystem:
# Create a projects directory in your Linux home
mkdir -p ~/projects
# Copy an existing project from Windows
cp -r /mnt/d/projects/my-app ~/projects/my-app
# Or clone fresh
cd ~/projects
git clone https://github.com/your-org/your-repo.git
From this point forward, do all development work inside ~/projects/. Access these files from Windows Explorer if needed via the \\wsl$\Ubuntu\home\<user>\projects UNC path.
Note from official docs: Disk read performance penalties when working across file systems on WSL may result in fewer-than-expected search matches when using Claude Code. The
/doctorcommand will show Search as OK even in this case, so the only symptom is missing results. (Source)
Configuring .wslconfig for Maximum Performance
The .wslconfig file controls global WSL2 VM settings. It lives on the Windows side at C:\Users\<your-username>\.wslconfig.
Default Behavior (Before Tuning)
Without a .wslconfig, WSL2 uses these defaults:
| Setting | Default | Impact |
|---|---|---|
| memory | 50% of total RAM | On a 64 GB system, only 32 GB available to WSL |
| processors | All logical cores | Already optimal |
| swap | 25% of memory | 8 GB on default 32 GB config |
| autoMemoryReclaim | dropCache | Returns cache to host on idle |
| sparseVhd | false | VHD grows but never shrinks |
| networkingMode | NAT | Can cause IDE detection issues (also supports mirrored and virtioproxy) |
| dnsTunneling | true | Good for VPN compatibility |
| vmIdleTimeout | 60000 (ms) | Auto-shutdown idle VMs after 60 seconds |
| firewall | true | Hyper-V firewall filtering of WSL traffic |
Our Optimized .wslconfig
# C:\Users\<your-username>\.wslconfig
[wsl2]
# Allocate 50-75% of your total RAM (adjust for your system)
# 16 GB system -> memory=10GB
# 32 GB system -> memory=22GB
# 64 GB system -> memory=48GB
memory=48GB
# All logical threads (adjust to match your CPU)
processors=20
# Generous swap prevents OOM-kills during heavy builds
swap=16GB
# Share host network interfaces directly (no NAT)
# WARNING: This breaks Docker Desktop and Kubernetes -- omit if using containers
networkingMode=mirrored
# Route DNS through Windows stack for VPN/DoH compatibility
dnsTunneling=true
# Inherit Windows proxy settings automatically
autoProxy=true
[experimental]
# Return unused memory to Windows gradually
autoMemoryReclaim=gradual
# Auto-shrink the virtual disk file
sparseVhd=true
Rationale for Each Setting
memory (50-75% of total RAM): On our 64 GB system, we allocate 48 GB to WSL2, leaving 16 GB for Windows. Scale this to your hardware -- the formula is "total RAM minus what Windows and your desktop apps need." If you run Docker Desktop alongside WSL2, account for Docker's own memory allocation. The autoMemoryReclaim=gradual setting ensures unused memory is returned to Windows over time, so this is a ceiling, not a reservation.
| Your System RAM | Recommended WSL2 Memory | Leave for Windows |
|---|---|---|
| 16 GB | 10 GB | 6 GB |
| 32 GB | 22 GB | 10 GB |
| 64 GB | 48 GB | 16 GB |
| 128 GB | 96 GB | 32 GB |
processors: Set to your total logical thread count. Claude Code benefits from parallel ripgrep searches and concurrent build processes. Run nproc in WSL to see your count.
swap=16GB: Provides headroom for memory spikes. Better to swap briefly than to OOM-kill a long-running Claude Code session.
networkingMode=mirrored: This improves localhost connectivity between Windows and WSL2, simplifying MCP server communication and port access.
Docker Warning:
networkingMode=mirroredis known to cause port binding failures, container connectivity issues, and Kubernetes startup problems. If you use Docker Desktop, Docker Compose, or any container tooling, omit this setting and use the default NAT mode. See rancher-desktop #6517 and docker-for-win #13807 for details.
dnsTunneling=true: Improves DNS compatibility with VPNs and corporate networks. DNS requests are tunneled through the Windows networking stack rather than using a NAT-based proxy. This removes the 3-DNS-server limitation in /etc/resolv.conf and supports encrypted DNS (DoH/DoT).
autoProxy=true: Automatically inherits Windows HTTP proxy settings, useful in corporate environments.
autoMemoryReclaim=gradual: The gradual mode slowly returns cached memory to Windows when CPU usage is low. The alternative dropCache is more aggressive but can cause brief performance dips when the cache is needed again. Either is better than disabled.
sparseVhd=true: Makes the WSL2 virtual disk file (.vhdx) automatically release unused space back to Windows. Without this, the VHD only grows -- even after you delete files inside WSL. Note that in practice, automatic compaction can be inconsistent -- you may still need to manually compact periodically (see Disk Space Management below).
Applying Changes
After editing .wslconfig, you must restart WSL:
# In PowerShell or CMD
wsl --shutdown
Then reopen your WSL terminal. Changes take effect on the next WSL boot.
Configuring /etc/wsl.conf
The wsl.conf file controls per-distribution settings. It lives inside the WSL filesystem at /etc/wsl.conf.
Our Configuration
# /etc/wsl.conf
[boot]
systemd=true
[automount]
enabled=true
options=metadata,umask=22,fmask=11
[network]
generateHosts=true
generateResolvConf=true
[interop]
enabled=true
appendWindowsPath=true
[gpu]
enabled=true
[time]
useWindowsTimezone=true
Key Settings Explained
systemd=true: Enables systemd as the init system. This is required for services like Docker, cron jobs, and any systemd-managed daemons. Some MCP servers may also depend on systemd. The trade-off is a slightly slower WSL boot time (~1-2 seconds).
automount options:
metadata: Enables Linux file permission metadata on Windows drives. Without this, all files on/mnt/cappear as owned by root with 777 permissions, which breaks tools that check permissions.umask=22: Sets default directory permissions to 755 on mounted Windows drives.fmask=11: Sets default file permissions to 666 on mounted Windows drives (no execute bit for files).
generateResolvConf=true: Let WSL manage DNS automatically. Combined with dnsTunneling=true in .wslconfig, this gives the best DNS experience. Only set this to false if you need to manually configure DNS servers.
gpu enabled=true: Enables GPU passthrough for Linux applications (default). Required for CUDA-accelerated AI/ML workloads. See the GPU section below.
useWindowsTimezone=true: Syncs WSL timezone with Windows (default). Prevents timestamp mismatches between Windows and Linux tools.
appendWindowsPath=true: Adds Windows executables to your WSL PATH, allowing you to run code . (VS Code), explorer.exe ., and other Windows tools from WSL. The Anthropic documentation explicitly warns against disabling this because it breaks the ability to call Windows executables from WSL. The downside is that Windows PATH entries can shadow Linux binaries -- if you see which node pointing to /mnt/c/..., the fix is to ensure your Linux nvm/node appears earlier in your PATH (see Shell Environment Setup), not to disable appendWindowsPath.
Shell Environment Setup
A well-configured shell makes Claude Code sessions more productive.
Recommended .bashrc Additions
# ~/.bashrc additions for Claude Code development
# ----- History -----
HISTSIZE=50000
HISTFILESIZE=50000
HISTCONTROL=ignoredups:erasedups
shopt -s histappend
# ----- Claude Code API Key -----
# Store your API key as an environment variable, not in config files.
# Claude Code automatically inherits environment variables from the shell.
export ANTHROPIC_API_KEY="sk-ant-xxxxx"
# ----- Telemetry (optional) -----
# If you experience connection errors (TLS handshake failures to
# statsig.anthropic.com), disable telemetry:
# export DISABLE_TELEMETRY=1
# ----- Auto-update control (optional) -----
# Uncomment to manage updates manually with `claude update`:
# export DISABLE_AUTOUPDATER=1
# ----- Default working directory -----
# Start in your projects directory if running interactively
if [[ $- == *i* ]] && [[ -d ~/projects ]]; then
cd ~/projects
fi
# ----- nvm (if using npm-installed Claude Code or Node.js tools) -----
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
# ----- Useful aliases -----
alias cc='claude'
alias ccc='claude --continue'
alias ccr='claude --resume'
PATH Hygiene
A common WSL issue is duplicate or conflicting PATH entries. Check for duplicates:
echo $PATH | tr ':' '\n' | sort | uniq -d
If you see duplicates, consolidate your PATH exports to a single location (.bashrc or .profile, not both). When using nvm, ensure the nvm-managed Node path appears before any Windows Node path:
# Verify Linux Node is used, not Windows
which node
# Should output: /home/<user>/.nvm/versions/node/v24.13.0/bin/node
# NOT: /mnt/c/Program Files/nodejs/node
Networking and DNS Optimization
Networking problems are the most common source of Claude Code failures on WSL2. The symptoms range from "Unable to connect to Anthropic services" to silent timeouts.
Mirrored Networking Mode
Setting networkingMode=mirrored in .wslconfig (as shown above) is the most impactful networking change. In mirrored mode:
- WSL2 shares the host's network interfaces directly instead of using a NAT bridge
localhostworks bidirectionally between Windows and WSL- Port forwarding is automatic
- VPN connections in Windows are visible to WSL
Reminder: Mirrored networking breaks Docker Desktop and Kubernetes tooling. If you use containers, stick with the default NAT mode and configure port forwarding manually where needed.
WSL also supports a virtioproxy networking mode (using virtio-based proxy networking). As of WSL 2.3.25, if NAT mode fails, WSL automatically falls back to VirtioProxy. The old bridged mode has been deprecated since WSL 2.4.5.
If you use mirrored mode with Docker, the ignoredPorts experimental setting can help resolve port conflicts (e.g., port 53):
[experimental]
ignoredPorts=53,6000-6100
DNS Tunneling
DNS tunneling (dnsTunneling=true in .wslconfig) routes DNS queries through the Windows networking stack using a virtualization feature rather than network packets. Benefits:
- Removes the 3-DNS-server limitation in
/etc/resolv.conf - Automatically applies Windows DNS suffixes to WSL queries
- Supports encrypted DNS (DoH, DoT) configured in Windows
- Improves compatibility with VPNs that use Network Resolution Policy Table (NRPT) policies
If you are behind a corporate proxy, also ensure autoProxy=true is set so WSL inherits the Windows proxy configuration.
Manual DNS Configuration (Fallback)
If automatic DNS is not working, you can manually configure it:
# 1. Disable auto-generation in /etc/wsl.conf
sudo tee -a /etc/wsl.conf <<EOF
[network]
generateResolvConf=false
EOF
# 2. Remove the symlink and create a static file
sudo rm /etc/resolv.conf
sudo tee /etc/resolv.conf <<EOF
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1
EOF
# 3. Restart WSL
# (from PowerShell) wsl --shutdown
Corporate Proxy Issues
If Claude Code shows "Unable to connect" behind a corporate proxy (Issue #332), set the proxy environment variables:
export HTTP_PROXY="http://proxy.corp.example.com:8080"
export HTTPS_PROXY="http://proxy.corp.example.com:8080"
export NO_PROXY="localhost,127.0.0.1,.corp.example.com"
System Limits and File Watching
Claude Code and its associated tooling (VS Code, language servers, file watchers) consume inotify watches and file descriptors. WSL2 defaults are generally adequate for most projects, but worth verifying.
Check Current Limits
# inotify watches (how many files can be watched for changes)
cat /proc/sys/fs/inotify/max_user_watches
# Open file descriptor limit
ulimit -n
Default vs Optimized
| Limit | WSL2 Default | Recommended | Notes |
|---|---|---|---|
max_user_watches | 8,192 | 524,288 | Default is low for large projects |
Open files (ulimit -n) | 1,024 | 65,535+ | Prevents "too many open files" |
Increasing inotify Watches
If your max_user_watches is at the default 8,192, increase it:
# Temporary (resets on WSL restart)
sudo sysctl fs.inotify.max_user_watches=524288
# Permanent
echo "fs.inotify.max_user_watches=524288" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
A value of 524,288 consumes approximately 540 MB of kernel memory and is the value recommended by VS Code for large workspaces.
Increasing Open Files Limit
# Add to /etc/security/limits.conf
sudo tee -a /etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65535
EOF
Important: inotify watches on files stored in
/mnt/c(Windows drives) do not reliably trigger change notifications for Linux applications. This is a fundamental WSL2 limitation (WSL Issue #4739). This is yet another reason to keep your projects on the Linux filesystem.
VS Code Integration
VS Code is the most popular editor paired with Claude Code on WSL2. The WSL extension runs a VS Code server inside WSL, keeping all file I/O local to the Linux filesystem.
Setup
- Install the WSL extension in VS Code on Windows.
- Open a WSL terminal and run:
cd ~/projects/my-app
code .
This launches VS Code connected to the WSL backend. The title bar will show [WSL: Ubuntu].
Performance Tips
- Always open projects from the WSL filesystem, not from
/mnt/c. The VS Code server runs inside WSL, so accessing Windows files means double-crossing the 9P bridge. - Install extensions inside WSL: Some extensions (Python, linters, debuggers) must be installed separately in the WSL context. VS Code prompts you when this is needed.
- Disable unnecessary file watchers: If you have large
node_modulesor build directories, add them to VS Code'sfiles.watcherExclude:
{
"files.watcherExclude": {
"**/node_modules/**": true,
"**/.git/objects/**": true,
"**/dist/**": true,
"**/build/**": true
}
}
Using Claude Code Alongside VS Code
You can run Claude Code in VS Code's integrated terminal or in a separate WSL terminal window. Both approaches work. If you use VS Code's integrated terminal, Claude Code automatically detects the VS Code environment and can open files in the editor.
GPU Acceleration for AI/ML Workloads
If you're running local models or GPU-accelerated tasks alongside Claude Code, WSL2 supports NVIDIA CUDA passthrough without installing Linux GPU drivers.
Setup
- Install the Windows NVIDIA driver (R495 or later). Do NOT install NVIDIA drivers inside WSL -- the Windows driver automatically creates
libcuda.sostubs in WSL. - Ensure
[gpu] enabled=trueis set in/etc/wsl.conf(it's the default). - Verify GPU access:
nvidia-smi
What Works
- CUDA up to 13.1 (Pascal and later architectures)
- PyTorch 2.7, TensorFlow 2.18, RAPIDS 22.04+ (single-GPU)
- NVIDIA Container Toolkit v2.6.0+ for GPU-accelerated Docker containers
- DirectML for non-NVIDIA GPUs (AMD, Intel)
Limitations
- Unified Memory is not fully available
- Pinned memory is limited
- Multi-GPU device selection is restricted (Docker only supports
--gpus all) - GPU profiling tools are still in preview
For most Claude Code workflows (which use cloud APIs, not local GPU), this section won't apply. But if you're fine-tuning models, running local inference, or doing ML development alongside Claude Code, WSL2's GPU support is production-ready for single-GPU workloads.
Security: API Keys and Environment Variables
Do Not Store Keys in Config Files
I'll be honest: do what I say here, not what I've done. I have personally committed API keys to public repos -- twice. Credit to OpenAI's security team, who scan public repositories for exposed keys and send you a polite but deeply shameful email asking you to do better. Anthropic and other providers do similar scanning. It's a safety net, not a strategy.
Claude Code's ~/.claude/settings.json is a JSON configuration file that should contain permissions and hooks (lifecycle automations like auto-formatting edited files or blocking writes to protected files), not secrets. API keys stored in files on disk are more likely to be accidentally committed, backed up to cloud storage, or exposed through file permission issues.
Use Environment Variables Instead
Claude Code automatically reads the ANTHROPIC_API_KEY environment variable from your shell. Store it in your .bashrc:
export ANTHROPIC_API_KEY="sk-ant-api03-xxxxxxxxxxxxx"
For additional security, consider using a secrets manager like pass to load keys dynamically rather than storing them in plaintext:
export ANTHROPIC_API_KEY=$(pass show anthropic/api-key)
MCP Servers and Path Translation
The Model Context Protocol (MCP) allows Claude Code to connect to external tools. The recommended way to add MCP servers is the CLI:
claude mcp add --transport stdio my-server -- npx -y @my-org/mcp-server
When running MCP servers from WSL, keep these WSL-specific considerations in mind:
- Use Linux paths, not Windows paths, in your MCP config. Use
/mnt/c/...only when the server needs to access Windows files. - If using nvm, MCP servers may not find
npxornodeon the PATH. Use full paths in your config or CLI command:
{
"mcpServers": {
"my-server": {
"type": "stdio",
"command": "/home/user/.nvm/versions/node/v24.13.0/bin/npx",
"args": ["-y", "@my-org/mcp-server"]
}
}
}
- With
networkingMode=mirrored,localhostworks bidirectionally between Windows and WSL, simplifying MCP servers that need cross-boundary communication.
Disk Space Management
WSL2 stores its filesystem in a .vhdx virtual hard disk file. By default, this file only grows -- even after you delete files inside WSL. Over time, it can consume tens of gigabytes of unnecessary Windows disk space.
Enable Automatic Sparse VHD
In your .wslconfig:
[experimental]
sparseVhd=true
This makes the VHD automatically release unused space. It must be set before the VHD is created, or you need to manually convert it. Note that automatic reclamation can be inconsistent -- check your VHD size periodically and compact manually if needed.
WSL CLI Disk Management (WSL 2.5+)
WSL 2.5 and later include built-in CLI commands that simplify disk management:
# Enable sparse mode on an existing distro
wsl --manage Ubuntu --set-sparse true
# Resize VHD (expand only)
wsl --manage Ubuntu --resize 500GB
# Move distro to another drive (replaces the old export/import workflow)
wsl --manage Ubuntu --move D:\WSL\Ubuntu
# Set VHD size at install time
wsl --install Ubuntu-24.04 --vhd-size 100GB
Manual VHD Compaction
If sparseVhd was not enabled from the start, or if automatic compaction isn't keeping up, manually reclaim space:
# Inside WSL: trim unused blocks
sudo fstrim /
# In PowerShell (as Administrator): shut down WSL first
wsl --shutdown
# Then compact the VHD
# Adjust the path to match your distribution
Optimize-VHD -Path "$env:LOCALAPPDATA\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx" -Mode Full
If Optimize-VHD is not available (requires Hyper-V tools), use diskpart:
# In an elevated command prompt
diskpart
select vdisk file="C:\Users\<user>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit
Keeping Your WSL Environment Updated
A tuned WSL2 environment still needs regular maintenance. Stale components cause subtle issues -- security patches lag, kernel features are missing, and Claude Code updates may depend on newer system libraries.
WSL Kernel and Platform
# In PowerShell: update WSL itself (kernel, platform, distro store)
wsl --update
Run this monthly. WSL kernel updates (currently 6.6.114.1 on WSL 2.7.0) bring performance improvements, filesystem fixes, and networking changes that directly affect Claude Code. Check your current version with:
wsl --version
Notable recent improvements: WSL 2.7.0 (December 2025) fixed a slow-boot issue where systemd-networkd-wait-online.service caused 30+ second delays, improved VirtioFS pass rates, and patched CVE-2025-55248.
Ubuntu System Packages
# Inside WSL
sudo apt update && sudo apt upgrade -y
This keeps system libraries, OpenSSL, and tools like git, curl, and bubblewrap current. Security patches for OpenSSL are especially important since Claude Code makes TLS connections to api.anthropic.com.
Claude Code
Claude Code auto-updates by default via its native installer. To check your current version and update status:
claude --version
claude doctor
If you disabled auto-updates with DISABLE_AUTOUPDATER=1, run claude update manually. You can also pin to the stable channel if you prefer less frequent updates:
curl -fsSL https://claude.ai/install.sh | bash -s stable
Node.js (if using nvm)
# Check for new LTS versions
nvm ls-remote --lts | tail -5
# Install and switch
nvm install --lts
nvm alias default lts/*
If you use the native Claude Code installer (recommended), Node.js version matters less since Claude Code ships its own runtime. But your project toolchains (Next.js, ESLint, etc.) still depend on it.
A Note on Stability
There was a high-priority issue with Claude Code's embedded Bun runtime (v1.3.5) causing segfaults on both Windows native and WSL2, caused by race conditions in Bun's async cleanup. If you experience unexplained crashes, check that issue for the latest status -- a Bun version bump from Anthropic should resolve it.
Known Issues and Workarounds
These are documented issues specific to running Claude Code on WSL2, sourced from the Anthropic GitHub repository.
Connection Errors / Fetch Failed
Issue: #2364 -- Claude Code reports "Unable to connect to Anthropic services" with ETIMEDOUT errors pointing to api.anthropic.com.
Root Cause: The actual failure is often a TLS handshake failure with the telemetry service (statsig.anthropic.com), not the API itself.
Fix:
export DISABLE_TELEMETRY=1
Telemetry Blocking Connections
Issue: #2481 -- Even with DISABLE_TELEMETRY=YES, Claude Code may still attempt connections to third-party services.
Fix: Set DISABLE_TELEMETRY=1 in your .bashrc. If the issue persists, also verify that your DNS and network configuration are working correctly (see the networking section above).
Corporate Proxy "Unable to Connect"
Issue: #332 -- Claude Code cannot reach Anthropic services behind a corporate proxy.
Fix: Set HTTP_PROXY and HTTPS_PROXY environment variables. Enable autoProxy=true in .wslconfig for automatic proxy inheritance.
JetBrains IDE Not Detected
Issue: #1232 -- "No available IDEs detected" when using JetBrains IDEs with Claude Code on WSL2.
Status: Officially resolved. Anthropic has published troubleshooting steps for JetBrains on WSL2 and fixed the underlying detection issue. A /config setting now allows auto-connecting to an IDE.
Root Cause: WSL2's default NAT networking prevented the IDE detection mechanism from communicating across the Windows/WSL boundary.
Fix: If you still experience detection issues, set networkingMode=mirrored in .wslconfig (confirmed working by multiple users) or add a Windows Firewall rule for the WSL2 subnet:
# Find your WSL2 IP
wsl hostname -I
# Create firewall rule (PowerShell as Administrator)
New-NetFirewallRule -DisplayName "Allow WSL2 Internal Traffic" `
-Direction Inbound -Protocol TCP -Action Allow `
-RemoteAddress 172.21.0.0/16 -LocalAddress 172.21.0.0/16
Note: JetBrains has documented compatibility concerns with mirrored mode that may cause other breakage. Test carefully before committing to mirrored networking for JetBrains specifically.
Interactive Mode Exits Immediately
Issue: #20115 -- Claude Code exits immediately after launching in interactive mode on some native WSL installations (confirmed on v2.1.15 through v2.1.19+).
Root Cause: Specific to the native binary installation. Non-interactive mode (claude -p "...") works fine on the same system.
Fix: If the native installer fails, fall back to the npm installation method:
npm install -g @anthropic-ai/claude-code
Also ensure you are using WSL2 (not WSL1) and Windows Terminal rather than the legacy console host.
Intermittent Connection Failures
Issue: #14550 -- Sporadic connection drops during Claude Code sessions on WSL2.
Root Cause: Two factors identified: (1) MTU mismatch -- WSL2 defaults to 1500 but the path to Anthropic's API may only support 1480, causing silent packet drops; (2) the Hyper-V virtual switch in NAT mode randomly drops packets.
Fix: Enable mirrored networking and DNS tunneling in .wslconfig. If you cannot use mirrored mode (e.g., Docker), try reducing the MTU:
sudo ip link set dev eth0 mtu 1400
If using a VPN, ensure the VPN client is compatible with WSL2 mirrored mode.
VS Code Extension Response Delay
Issue: #16429 -- Users reported 3-4 minute response delays in WSL2 with the VS Code Claude Code extension versions >= 2.0.74 (January 2026).
Fix: Downgrading to extension version 2.0.72 immediately resolved the issue. Later extension versions have reportedly fixed this. If you experience long delays specifically in VS Code's integrated terminal (but not in a standalone WSL terminal), check your extension version.
Claude in Chrome Crashes Claude Code on WSL2
Issue: #15362 -- Having Claude open in Chrome can interfere with Claude Code running in WSL2.
Fix: Close Claude in the browser while using Claude Code, or use separate browser profiles.
FAQ
Should I use WSL1 or WSL2 for Claude Code? WSL2. It runs a real Linux kernel, gives you native ext4 filesystem performance (~9x faster than cross-filesystem access), and is the only option that supports Claude Code's bubblewrap sandboxing.
How much RAM should I allocate to WSL2 for AI development?
50-75% of your total system RAM. On a 16 GB system, start with 10 GB. On 32 GB, try 22 GB. On 64 GB, 48 GB works well. The autoMemoryReclaim=gradual setting returns unused memory to Windows, so this is a ceiling, not a permanent allocation.
Why is Claude Code slow on WSL2?
The most common cause is working from Windows drives (/mnt/c/ or /mnt/d/) instead of the native Linux filesystem (~/). Move your projects to ~/projects/ for a ~9x filesystem performance improvement. Also check that your .wslconfig allocates enough memory and CPU threads.
Can I use Claude Code with Docker Desktop on WSL2?
Yes, but do not set networkingMode=mirrored in your .wslconfig. Mirrored networking is known to break Docker port binding and container connectivity. Use the default NAT mode instead.
How do I fix DNS resolution issues in WSL2?
First, enable dnsTunneling=true in .wslconfig. If that doesn't help, manually configure /etc/resolv.conf with public DNS servers (8.8.8.8, 1.1.1.1) after disabling auto-generation in /etc/wsl.conf.
Can I use Claude Code with VS Code Remote-WSL?
Yes. Install the VS Code WSL extension, then open projects from the WSL terminal with code .. Always open projects stored on the Linux filesystem, not from /mnt/c. Claude Code works in both the integrated terminal and a separate WSL terminal window.
Does Claude Code work with corporate VPNs on WSL2?
It can, but requires configuration. Enable dnsTunneling=true and autoProxy=true in .wslconfig. Set HTTP_PROXY and HTTPS_PROXY environment variables if needed. Common VPN clients (Cisco AnyConnect, Zscaler, GlobalProtect) can cause networking issues with WSL2 -- mirrored networking mode often helps, but test your specific setup.
Is there a GUI for WSL settings?
Yes. WSL now includes a Settings app (wslsettings) accessible from the Start menu. It provides a visual interface for the same settings you'd configure in .wslconfig. However, for the level of tuning in this guide, editing .wslconfig directly gives you more control and is easier to version-control.
How do I share Git credentials between Windows and WSL2? Configure the Windows Git Credential Manager as the helper in WSL:
git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/bin/git-credential-manager.exe"
Checklist
Use this as a quick audit for your own setup:
- WSL2 installed and updated (
wsl --update, verify withwsl --version) - Ubuntu 24.04 LTS (or 20.04+) as the distribution
-
.wslconfigconfigured with appropriate memory, CPU, networking -
/etc/wsl.confconfigured with systemd, metadata mount options - Projects stored on Linux filesystem (
~/projects), not/mnt/c - Claude Code installed via native installer (
curl -fsSL https://claude.ai/install.sh | bash) -
claude doctorpasses all checks - Sandbox dependencies installed (
bubblewrap,socat) - API key stored in environment variable, not config file
- inotify watches at 524,288+ (
cat /proc/sys/fs/inotify/max_user_watches) - VS Code WSL extension installed; projects opened from WSL side
-
DISABLE_TELEMETRY=1set if experiencing connection errors -
sparseVhd=trueenabled for automatic disk space reclamation - Shell history increased to 50,000+
-
networkingMode=mirroredset for IDE and MCP compatibility (omit if using Docker) - WSL kernel updated (
wsl --updatefrom PowerShell) - Ubuntu packages updated (
sudo apt update && sudo apt upgrade)
Sources
Anthropic / Claude Code
- Claude Code Overview
- Claude Code Setup Documentation
- Claude Code Troubleshooting
- Claude Code Best Practices
- Claude Code MCP Documentation
- Claude Code Sandboxing
- Claude Code Hooks Guide
- Claude Code Settings Reference
- Claude Code Security
- Claude Code Memory (CLAUDE.md)
GitHub Issues
- #16429 -- VS Code extension response delay on WSL2
- #2364 -- Connection errors / fetch failed
- #2481 -- Telemetry blocking connections on WSL
- #332 -- Unable to connect behind corporate proxy
- #1232 -- JetBrains IDE not detected in WSL
- #20115 -- Interactive mode exits immediately
- #14550 -- Intermittent connection failures on WSL2
- #15362 -- Chrome Claude crashes Claude Code on WSL2
Microsoft WSL Documentation
- WSL Is Now Open Source (Build 2025)
- WSL Open Source Overview
- WSL 2.7.0 Release Notes
- Advanced WSL Configuration (.wslconfig and wsl.conf)
- Comparing WSL 1 and WSL 2
- Working Across File Systems in WSL
- WSL Disk Space Management
- Get Started with VS Code and WSL
- WSL inotify Watches Issue #4293
- WSL File Change Notifications Issue #4739
VS Code
GPU / CUDA
Benchmarks
Community Resources
Ready to Put This Into Practice?
Take our free 5-minute assessment to see where your organization stands, or talk to us about your situation.
Not ready to talk? Stay in the loop.
Get AI strategy insights for mid-market leaders — no spam, unsubscribe anytime.
Related Posts
View all posts
