<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>WSL2 on kenji.blog</title><link>http://kenji.blog/en/tags/wsl2/</link><description>Recent content in WSL2 on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 07:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/en/tags/wsl2/index.xml" rel="self" type="application/rss+xml"/><item><title>Hyper-V vs WSL2: Comparing Virtualization Technologies on Windows</title><link>http://kenji.blog/en/p/hyper-v-vs-wsl2-windows-virtualization/</link><pubDate>Sun, 13 Sep 2026 07:00:00 +0900</pubDate><guid>http://kenji.blog/en/p/hyper-v-vs-wsl2-windows-virtualization/</guid><description>&lt;img src="http://kenji.blog/p/hyper-v-vs-wsl2-windows-virtualization/img/eyecatch.jpg" alt="Featured image of post Hyper-V vs WSL2: Comparing Virtualization Technologies on Windows" />&lt;h2 id="1-introduction-the-evolution-of-virtualization-on-windows">1. Introduction: The Evolution of Virtualization on Windows
&lt;/h2>&lt;p>Virtualization technology on the Windows platform has evolved dramatically over the past few decades. In the past, third-party Type 2 hypervisors (such as VMware Workstation and VirtualBox) were the mainstream. However, since Microsoft introduced &amp;ldquo;Hyper-V&amp;rdquo; in Windows Server 2008, Type 1 hypervisors have also been integrated into desktop OSs like Windows 10/11.&lt;/p>
&lt;p>In recent years, the technology that has garnered the most attention among developers is &amp;ldquo;WSL2 (Windows Subsystem for Linux 2)&amp;rdquo;. While WSL1 relied on system call translation, WSL2 employs a &amp;ldquo;Lightweight Utility VM&amp;rdquo; based on Hyper-V technology, achieving full Linux compatibility and a dramatic leap in performance.&lt;/p>
&lt;p>In this article, we will thoroughly compare and explain the architecture, performance (CPU, memory, disk I/O), network configuration, and optimal use cases of these two powerful virtualization technologies—the full-featured &amp;ldquo;Hyper-V&amp;rdquo; and the developer-experience-focused &amp;ldquo;WSL2&amp;rdquo;—along with deep technical details.&lt;/p>
&lt;hr>
&lt;h2 id="2-basic-theory-of-hypervisors-and-architecture-comparison">2. Basic Theory of Hypervisors and Architecture Comparison
&lt;/h2>&lt;p>To understand virtualization technologies, classifying hypervisor (Virtual Machine Monitor: VMM) types is essential.&lt;/p>
&lt;h3 id="21-differences-between-type-1-and-type-2-hypervisors">2.1. Differences between Type 1 and Type 2 Hypervisors
&lt;/h3>&lt;p>A hypervisor is a software layer that abstracts hardware access, allowing multiple OSs (guest OSs) to run simultaneously on a single physical machine.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Type 1 (Bare-metal)&lt;/strong>: Runs directly on the hardware. There is no concept of a host OS (strictly speaking, a privileged management OS may exist), offering extremely low overhead, high performance, and high security. Examples: Hyper-V, VMware ESXi, Xen.&lt;/li>
&lt;li>&lt;strong>Type 2 (Hosted)&lt;/strong>: Runs as an application on a host OS (such as Windows or macOS). Since all hardware access goes through the host OS, the overhead is larger. Examples: VMware Workstation, Oracle VirtualBox.&lt;/li>
&lt;/ul>
&lt;p>Windows Hyper-V is a pure &lt;strong>Type 1 hypervisor&lt;/strong>. When Hyper-V is enabled, the Windows OS that the user normally operates actually starts running inside a special virtual machine called the &amp;ldquo;Root Partition&amp;rdquo;.&lt;/p>
&lt;h3 id="22-hyper-v-architecture-details">2.2. Hyper-V Architecture Details
&lt;/h3>&lt;p>The Hyper-V architecture adopts a microkernel design and is based on logical isolation units called Partitions.&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;Hardware (CPU, RAM, Disk, NIC)&amp;#34;] --&amp;gt; B[&amp;#34;Windows Hypervisor (Ring -1)&amp;#34;]
B --&amp;gt; C[&amp;#34;Root Partition (Windows OS)&amp;#34;]
B --&amp;gt; D[&amp;#34;Child Partition 1 (Windows VM)&amp;#34;]
B --&amp;gt; E[&amp;#34;Child Partition 2 (Linux VM)&amp;#34;]
C --&amp;gt; F[&amp;#34;VMBus (Virtual Machine Bus)&amp;#34;]
D --&amp;gt; F
E --&amp;gt; F
C --&amp;gt; G[&amp;#34;VID (Virtualization Infrastructure Driver)&amp;#34;]
C --&amp;gt; H[&amp;#34;VMWP.exe (Worker Process)&amp;#34;]
&lt;/pre>
&lt;ul>
&lt;li>&lt;strong>Windows Hypervisor&lt;/strong>: Runs at the most privileged level of the CPU (Ring -1 or VMX Root Mode) and is responsible only for memory allocation and CPU scheduling. It does not contain device drivers.&lt;/li>
&lt;li>&lt;strong>Root Partition&lt;/strong>: The partition where the host Windows OS runs. It possesses all device drivers and controls the hardware directly. It also provides management functions for child partitions (such as WMI providers and VMWP.exe).&lt;/li>
&lt;li>&lt;strong>Child Partition&lt;/strong>: The partition where a guest OS runs. Direct access to hardware is not permitted, and it sends I/O requests (Synthetic I/O) to the root partition via a logical memory sharing bus called &amp;ldquo;VMBus&amp;rdquo;.&lt;/li>
&lt;/ul>
&lt;h3 id="23-mechanism-of-wsl2-and-lightweight-utility-vm">2.3. Mechanism of WSL2 and Lightweight Utility VM
&lt;/h3>&lt;p>Although WSL2 utilizes the same underlying Type 1 hypervisor technology as Hyper-V, it uses a subset of features called the &amp;ldquo;Virtual Machine Platform (VMP)&amp;rdquo; which differs from full-featured Hyper-V virtual machines.&lt;/p>
&lt;p>The &amp;ldquo;Lightweight Utility VM&amp;rdquo; adopted in WSL2 completely eliminates the emulation of legacy hardware (such as virtual BIOS or virtual motherboards) present in traditional VMs.&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;Windows Host OS (User Space)&amp;#34;]
B[&amp;#34;NTFS File System&amp;#34;]
C[&amp;#34;9P Protocol Server (Plan 9)&amp;#34;]
D[&amp;#34;Lightweight Utility VM (Linux Kernel)&amp;#34;]
E[&amp;#34;ext4.vhdx (Virtual Disk)&amp;#34;]
F[&amp;#34;Linux User Space (WSL2 Distributions)&amp;#34;]
A --&amp;gt; C
C --&amp;gt;| Cross-OS File Sharing | D
D --&amp;gt; E
D --&amp;gt; F
&lt;/pre>
&lt;p>The greatest features of WSL2 are its &lt;strong>fast startup&lt;/strong> and &lt;strong>seamless integration with the host OS&lt;/strong>. The Linux kernel boots in less than a second, and it accesses the Windows file system (NTFS) via Plan 9&amp;rsquo;s &lt;code>9P&lt;/code> network file system protocol.&lt;/p>
&lt;hr>
&lt;h2 id="3-thorough-performance-analysis-computational-resources-and-io">3. Thorough Performance Analysis: Computational Resources and I/O
&lt;/h2>&lt;p>Virtual machine performance is expressed as the sum of overheads across CPU, memory, and disk I/O components.&lt;/p>
&lt;h3 id="31-cpu-and-context-switch-overhead">3.1. CPU and Context Switch Overhead
&lt;/h3>&lt;p>Both Hyper-V and WSL2 use hardware-assisted virtualization (Intel VT-x / AMD-V). CPU instructions are basically executed at native speed, but when privileged instructions are executed or I/O operations occur, an interrupt called &amp;ldquo;VM Exit&amp;rdquo; is triggered, resulting in a context switch to the hypervisor.&lt;/p>
&lt;p>The CPU overhead $T_{overhead}$ at this time can be expressed by the following mathematical model:&lt;/p>
$$ T_{overhead} = \sum_{i=1}^{N} (t_{vm\_exit} + t_{hypercall\_process} + t_{vm\_entry}) $$&lt;p>Where:&lt;/p>
&lt;ul>
&lt;li>$N$: Number of VM Exits occurring per unit time&lt;/li>
&lt;li>$t_{vm\_exit}$: Transition time from the guest to the hypervisor&lt;/li>
&lt;li>$t_{hypercall\_process}$: Processing time for I/O operations or interrupts via VMBus&lt;/li>
&lt;li>$t_{vm\_entry}$: Return time from the hypervisor to the guest&lt;/li>
&lt;/ul>
&lt;p>Because WSL2 lacks legacy emulation, $t_{hypercall\_process}$ is heavily optimized and extremely small. Therefore, for pure CPU operations (such as kernel compilation or machine learning model inference), the performance degradation remains within a few percent compared to a bare-metal environment.&lt;/p>
&lt;h3 id="32-memory-allocation-mechanisms">3.2. Memory Allocation Mechanisms
&lt;/h3>&lt;p>There are distinct differences in design philosophy between the two regarding memory management approaches.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Hyper-V (Dynamic Memory)&lt;/strong>: The root partition dynamically allocates and reclaims memory according to the memory demands of the guest VM. However, memory secured as page cache within the guest OS tends not to be released unless the system is under pressure.&lt;/li>
&lt;li>&lt;strong>WSL2 (Dynamic Memory Reclaim)&lt;/strong>: WSL2 has its own mechanism to periodically return (reclaim) memory—including caches—that is no longer needed inside the Linux VM back to the Windows host. While early WSL2 versions had an issue where Linux page caches exhausted Windows memory (bloat of the Vmmem process), this has now been improved by kernel patches.&lt;/li>
&lt;/ul>
&lt;h3 id="33-disk-io-characteristics-vhdx-vs-ext4vhdx">3.3. Disk I/O Characteristics (VHDX vs ext4.vhdx)
&lt;/h3>&lt;p>Disk I/O is the component most likely to become a bottleneck in virtual machine performance.&lt;/p>
&lt;p>The I/O latency $L_{total}$ is calculated as follows:&lt;/p>
$$ L_{total} = L_{guest\_fs} + L_{vmbus} + L_{host\_fs} + L_{physical\_disk} $$&lt;p>&lt;strong>In the case of Hyper-V&lt;/strong>:
A typical Hyper-V guest uses a virtual disk in the &lt;code>VHDX&lt;/code> format. I/O requests issued from the file system (ext4 or NTFS) within the guest OS pass through the VMBus block device storage driver (storvsc) and are processed as accesses to the VHDX file on NTFS on the Windows side.&lt;/p>
&lt;p>&lt;strong>In the case of WSL2&lt;/strong>:
WSL2&amp;rsquo;s Linux distributions run on a native ext4 file system built within a dedicated &lt;code>ext4.vhdx&lt;/code> file. File operations inside Linux (e.g., within the &lt;code>~&lt;/code> directory) demonstrate native performance equivalent to the aforementioned Hyper-V.
However, &lt;strong>when accessing files on the Windows side (such as &lt;code>/mnt/c/&lt;/code>) from WSL2&amp;rsquo;s Linux&lt;/strong>, or vice versa, the processing differs significantly. The &lt;code>9P (Plan 9 File System Protocol)&lt;/code> is used for this cross-OS access.&lt;/p>
$$ L_{cross\_os} = L_{9p\_client} + L_{socket\_transfer} + L_{9p\_server} + L_{ntfs} $$&lt;p>Access via this 9P protocol involves significant serialization processing overhead. In scenarios involving massive read/write operations of small files (e.g., &lt;code>npm install&lt;/code> or Git operations in a Node.js project located in a Windows directory), performance drops significantly (sometimes with more than 10 times the delay).
Therefore, &lt;strong>when using WSL2, the golden rule is to always place project files on the Linux native file system (under &lt;code>~/&lt;/code>)&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h2 id="4-network-structure-nat-default-switch-bridged">4. Network Structure: NAT, Default Switch, Bridged
&lt;/h2>&lt;p>Network flexibility is one of the major differences between Hyper-V and WSL2.&lt;/p>
&lt;h3 id="41-wsl2-network-nat-based">4.1. WSL2 Network (NAT-based)
&lt;/h3>&lt;p>By default, the WSL2 network is configured with &amp;ldquo;NAT (Network Address Translation)&amp;rdquo; using Hyper-V&amp;rsquo;s virtual switch technology.
The Linux VM is automatically assigned a private IP address (e.g., &lt;code>172.20.x.x&lt;/code>) different from the Windows host. A mechanism is built-in where access to &lt;code>localhost&lt;/code> from the Windows host is forwarded to services (ports) running inside WSL2, allowing developers to test web servers without having to be mindful of the network.&lt;/p>
&lt;p>Recently, a new network mode called &amp;ldquo;Mirrored mode&amp;rdquo; was introduced in preview versions of WSL2. This aims to improve IPv6 support and VPN connection compatibility (configurable via &lt;code>.wslconfig&lt;/code>).&lt;/p>
&lt;h3 id="42-hyper-v-virtual-switch">4.2. Hyper-V Virtual Switch
&lt;/h3>&lt;p>Hyper-V enables advanced, enterprise-level network construction. Through the &amp;ldquo;Virtual Switch Manager&amp;rdquo;, it mainly provides three modes:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>External&lt;/strong>: Binds the host machine&amp;rsquo;s physical NIC to the virtual switch, allowing the guest VM to directly join the physical network (bridge connection). The VM obtains an IP from the same subnet as the physical network via a DHCP server.&lt;/li>
&lt;li>&lt;strong>Internal&lt;/strong>: Only allows communication between the host OS and VMs, as well as between VMs. Direct access to external networks is not possible.&lt;/li>
&lt;li>&lt;strong>Private&lt;/strong>: Only allows communication between VMs, cutting off communication with the host OS. Used for building isolated testing environments.&lt;/li>
&lt;/ol>
&lt;h3 id="43-advanced-hyper-v-network-construction-using-powershell">4.3. Advanced Hyper-V Network Construction using PowerShell
&lt;/h3>&lt;p>In development or testing environments, when you want to build a customized NAT network for VMs, PowerShell allows for detailed control. Below is an example script to create an internal virtual switch, configure NAT on it, and provide internet access to a VM.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 1. Create Internal Virtual Switch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$SwitchName&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;HyperV-NatSwitch&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">New-VMSwitch&lt;/span> &lt;span class="n">-SwitchName&lt;/span> &lt;span class="nv">$SwitchName&lt;/span> &lt;span class="n">-SwitchType&lt;/span> &lt;span class="n">Internal&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 2. Set IP address to the virtual NIC on the host side (IP that acts as a gateway)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$GatewayIP&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;192.168.100.1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$NetPrefix&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mf">24&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$InterfaceAlias&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;vEthernet (&lt;/span>&lt;span class="nv">$SwitchName&lt;/span>&lt;span class="s2">)&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">New-NetIPAddress&lt;/span> &lt;span class="n">-IPAddress&lt;/span> &lt;span class="nv">$GatewayIP&lt;/span> &lt;span class="n">-PrefixLength&lt;/span> &lt;span class="nv">$NetPrefix&lt;/span> &lt;span class="n">-InterfaceAlias&lt;/span> &lt;span class="nv">$InterfaceAlias&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 3. Configure NAT Network&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$NatName&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;HyperV-NatNetwork&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$NatSubnet&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;192.168.100.0/24&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">New-NetNat&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="nv">$NatName&lt;/span> &lt;span class="n">-InternalIPInterfaceAddressPrefix&lt;/span> &lt;span class="nv">$NatSubnet&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Verification command&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-NetNat&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>With this configuration, by manually setting an IP of &lt;code>192.168.100.x&lt;/code> and a gateway of &lt;code>192.168.100.1&lt;/code> on a designated Hyper-V guest, you can build a custom NAT segment that can communicate externally via the host.&lt;/p>
&lt;hr>
&lt;h2 id="5-use-cases-and-practical-selection-guide">5. Use Cases and Practical Selection Guide
&lt;/h2>&lt;p>Based on the differences in architecture and performance discussed so far, we define under what circumstances which technology should be adopted.&lt;/p>
&lt;h3 id="51-scenarios-for-choosing-wsl2">5.1. Scenarios for Choosing WSL2
&lt;/h3>&lt;p>WSL2 is specifically designed to &amp;ldquo;improve developer productivity.&amp;rdquo; It is optimal for the following uses:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Web Development and Cloud-Native Development&lt;/strong>: Container development using Docker Desktop (WSL2 backend) or Podman.&lt;/li>
&lt;li>&lt;strong>Using Linux-specific Tools&lt;/strong>: When routinely using bash, grep, awk, sed, or GCC/Clang compilers meant for Linux.&lt;/li>
&lt;li>&lt;strong>GUI Applications (WSLg)&lt;/strong>: When you want to run Linux X11/Wayland applications seamlessly on the Windows desktop.&lt;/li>
&lt;li>&lt;strong>Machine Learning and AI Development&lt;/strong>: High-speed training with TensorFlow or PyTorch using GPU passthrough capabilities (NVIDIA CUDA on WSL).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Note&lt;/strong>: You may face restrictions if you wish to deeply customize the kernel, or build complex services heavily dependent on systemd (systemd is currently supported, but is disabled or restricted by default).&lt;/p>
&lt;h3 id="52-scenarios-for-choosing-hyper-v">5.2. Scenarios for Choosing Hyper-V
&lt;/h3>&lt;p>Hyper-V is intended for &amp;ldquo;infrastructure virtualization and complete isolation.&amp;rdquo; It is essential for the following uses:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Running Windows VMs&lt;/strong>: When running different versions of Windows (such as Windows Server or older Windows 10) as test environments.&lt;/li>
&lt;li>&lt;strong>Nested Virtualization&lt;/strong>: When you want to run a virtual machine (Hyper-V or KVM) inside another virtual machine. Indispensable for infrastructure engineers&amp;rsquo; validation environments.&lt;/li>
&lt;li>&lt;strong>Advanced Network Requirements&lt;/strong>: When network configurations must be strictly controlled, such as external bridge connections (joining the same LAN), VLAN tagging, or allocating multiple NICs.&lt;/li>
&lt;li>&lt;strong>Snapshots (Checkpoints)&lt;/strong>: The ability to save a VM&amp;rsquo;s state at a specific point in time and instantly roll back to it whenever needed. Extremely useful for destructive software testing or malware analysis.&lt;/li>
&lt;li>&lt;strong>Fixed Resource Allocation&lt;/strong>: When you want to strictly fix the number of CPU cores and memory amount to minimize the impact on the host OS.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="6-consideration-of-io-throughput-through-mathematical-models-appendix">6. Consideration of I/O Throughput through Mathematical Models (Appendix)
&lt;/h2>&lt;p>As a system engineer, when determining the I/O performance limits of both, it is crucial to theoretically understand the relationship between throughput $S$ and block size $B$.&lt;/p>
&lt;p>Data transfer throughput $S$ is the amount of data transferred per unit time, and is modeled as follows:&lt;/p>
$$ S(B) = \frac{B}{L_{setup} + \frac{B}{R_{max}}} $$&lt;ul>
&lt;li>$B$: Block size (Bytes)&lt;/li>
&lt;li>$L_{setup}$: Fixed latency associated with I/O request setup and context switching&lt;/li>
&lt;li>$R_{max}$: Hardware&amp;rsquo;s maximum bandwidth for copying and device transfers&lt;/li>
&lt;/ul>
&lt;p>In file accesses via WSL2&amp;rsquo;s 9P protocol, this $L_{setup}$ becomes extremely large (due to socket communication and protocol serialization/deserialization). Therefore, when the block size $B$ is small (massive read/write of fine files around a few KBs), the effect of $L_{setup}$ in the denominator becomes dominant, and the throughput $S$ degrades dramatically.
Conversely, in VHDX access via Hyper-V&amp;rsquo;s VMBus, $L_{setup}$ is optimized to a level close to hardware interrupts, allowing it to maintain high IOPS even with small blocks.&lt;/p>
&lt;p>This mathematical reality serves as the logical foundation for the best practice that &amp;ldquo;you must not place project files on the Windows side in WSL2&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="7-conclusion-two-coexisting-virtualization-technologies">7. Conclusion: Two Coexisting Virtualization Technologies
&lt;/h2>&lt;p>Hyper-V and WSL2 are not a matter of one being superior to the other; they are &lt;strong>&amp;ldquo;two solutions with different purposes&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>WSL2&lt;/strong> is the &amp;ldquo;best integration tool&amp;rdquo; that breaks the shell of the Windows OS to seamlessly and swiftly deliver the Linux ecosystem to Windows users. It is no exaggeration to call it the ultimate CLI environment for developers.&lt;/li>
&lt;li>&lt;strong>Hyper-V&lt;/strong> is a &amp;ldquo;full-fledged hypervisor&amp;rdquo; that brings the robust isolation and management capabilities cultivated in enterprise data centers to the desktop. It is second to none in network construction, Windows OS testing, and infrastructure environment simulation.&lt;/li>
&lt;/ul>
&lt;p>In modern Windows environments, these two technologies do not compete on equal terms; they beautifully coexist on the same VM platform. By using the right tool for the right job depending on the purpose, Windows can truly become the most powerful and flexible engineering workstation in the world.&lt;/p></description></item><item><title>The Ultimate Development Environment Setup Guide for WSL2 (Windows Subsystem for Linux)</title><link>http://kenji.blog/en/p/wsl2-ultimate-development-setup-guide/</link><pubDate>Sat, 12 Sep 2026 23:00:00 +0900</pubDate><guid>http://kenji.blog/en/p/wsl2-ultimate-development-setup-guide/</guid><description>&lt;img src="http://kenji.blog/p/wsl2-ultimate-development-setup-guide/img/eyecatch.jpg" alt="Featured image of post The Ultimate Development Environment Setup Guide for WSL2 (Windows Subsystem for Linux)" />&lt;p>WSL2 (Windows Subsystem for Linux 2), which provides a Linux-native development environment on Windows, has become an indispensable tool in modern software development. However, there is a world of difference in performance and development experience between continuing to use it in its default state and understanding the architecture to apply appropriate tuning.&lt;/p>
&lt;p>In this article, starting with an explanation of the architecture that forms the foundation of WSL2, we will thoroughly explain all the steps to build the &amp;ldquo;ultimate development environment&amp;rdquo; demanded by professional engineers in a volume of over 10,000 characters. This covers settings to maximize performance, building a comfortable terminal environment, seamless integration with Docker and VS Code, and advanced network configurations.&lt;/p>
&lt;hr>
&lt;h2 id="1-wsl2-architecture-and-evolution-from-wsl1">1. WSL2 Architecture and Evolution from WSL1
&lt;/h2>&lt;p>To fully unleash the potential of WSL2, it is important to first understand its internal structure. The approach to running Linux binaries on Windows is fundamentally different between the first-generation WSL (WSL1) and WSL2.&lt;/p>
&lt;h3 id="wsl1-system-call-translation-layer">WSL1: System Call Translation Layer
&lt;/h3>&lt;p>WSL1 adopted a mechanism that translates Linux system calls into Windows NT APIs in real-time. Because this did not use a virtual machine (VM), it had the advantage of very low resource overhead. However, it was difficult to perfectly emulate complex system calls, such as file system I/O operations, which led to devastating performance degradation, especially in processes dealing with large numbers of small files, such as Node.js &lt;code>npm install&lt;/code> and Git repository operations.&lt;/p>
&lt;h3 id="wsl2-lightweight-utility-vm-and-a-complete-linux-kernel">WSL2: Lightweight Utility VM and a Complete Linux Kernel
&lt;/h3>&lt;p>In WSL2, the architecture was revamped, and an authentic Linux kernel built by Microsoft now runs directly on a &amp;ldquo;lightweight utility VM&amp;rdquo; utilizing a subset of the Hyper-V architecture. This ensures 100% compatibility for system calls and dramatically improves file I/O performance compared to WSL1 by using a virtual disk (VHDX) that utilizes the Linux-native ext4 file system.&lt;/p>
&lt;p>The following Mermaid diagram shows the structural differences between WSL1 and WSL2.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
subgraph &amp;#34;Windows OS Environment&amp;#34;
A[&amp;#34;Windows NT Kernel&amp;#34;]
A --&amp;gt; F[&amp;#34;NTFS File System (C: Drive)&amp;#34;]
end
subgraph &amp;#34;WSL2 Architecture&amp;#34;
B[&amp;#34;Hyper-V Hypervisor&amp;#34;]
B --&amp;gt; C[&amp;#34;Lightweight Utility VM&amp;#34;]
C --&amp;gt; D[&amp;#34;Linux Kernel (Microsoft)&amp;#34;]
D --&amp;gt; E[&amp;#34;Ubuntu User Space (glibc, bash, etc.)&amp;#34;]
D --&amp;gt; G[&amp;#34;ext4 Virtual Disk (.vhdx)&amp;#34;]
end
A -.-&amp;gt;|&amp;#34;Plan 9 (9P) Protocol Network File Share&amp;#34;| D
style B fill:#f9f,stroke:#333,stroke-width:2px
style D fill:#bbf,stroke:#333,stroke-width:2px
&lt;/pre>
&lt;p>An important lesson to be learned from this structure is: &lt;strong>&amp;ldquo;Access to files on the Linux side (inside the VHDX) is extremely fast, but access to files on the Windows side (&lt;code>/mnt/c/&lt;/code>) is very slow because it goes through the 9P protocol.&amp;rdquo;&lt;/strong> The source code of your projects must always be placed under the home directory (&lt;code>~&lt;/code>) on the WSL side.&lt;/p>
&lt;hr>
&lt;h2 id="2-mathematical-analysis-of-performance-why-is-wsl2-so-fast">2. Mathematical Analysis of Performance: Why is WSL2 so fast?
&lt;/h2>&lt;p>Let&amp;rsquo;s quantitatively evaluate the performance improvement of WSL2 using a mathematical model. One of the most time-consuming operations in software development is processing that involves a large amount of file I/O (e.g., library installation or building).&lt;/p>
&lt;p>The total execution time $T_{total}$ of a certain process is expressed as the sum of the computing time by the CPU $T_{compute}$ and the time taken for disk I/O $T_{io}$.&lt;/p>
$$ T_{total} = T_{compute} + T_{io} $$&lt;p>In the case of WSL1, because an overhead occurs in translating Linux-side operations into NTFS operations, the I/O time is modeled as follows. Here, $n$ is the number of file operations, $t_{ntfs\_syscall}$ is the execution time of the Windows-side system call, and $t_{trans}$ is the overhead of the translation layer.&lt;/p>
$$ T_{wsl1\_io} = \sum_{i=1}^{n} (t_{ntfs\_syscall_i} + t_{trans_i}) $$&lt;p>On the other hand, in WSL2, since the kernel issues I/O directly to the ext4 file system, the overhead is only a very small delay $t_{virt}$ due to virtualization.&lt;/p>
$$ T_{wsl2\_io} = \sum_{i=1}^{n} (t_{ext4_i} + t_{virt_i}) $$&lt;p>In a general file system, since $t_{ext4} \ll t_{ntfs\_syscall} + t_{trans}$, when $n$ is very large (performing tens to hundreds of thousands of file operations), the difference in I/O time between WSL1 and WSL2 grows exponentially.&lt;/p>
&lt;p>Also, assuming the overhead ratio of CPU computation in a virtualized environment is $\rho$, with modern hardware-assisted virtualization (Intel VT-x / AMD-V), it stays around $\rho \approx 0.01 \sim 0.03$ (1 to 3%). Therefore, even in pure computational tasks, it delivers a performance of $97\% \sim 99\%$ which is comparable to a native Linux environment.&lt;/p>
&lt;hr>
&lt;h2 id="3-installation-and-foundation-building">3. Installation and Foundation Building
&lt;/h2>&lt;p>On Windows 10/11, installing WSL2 has become very simple. Just open PowerShell with administrator privileges and run the following command.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># WSL2 and Ubuntu are installed by default&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-install&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># When specifying a specific distribution&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># You can check this with wsl --list --online&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-install&lt;/span> &lt;span class="n">-d&lt;/span> &lt;span class="n">Ubuntu&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">24.04&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>After installation, following a reboot, you will be prompted to set up a UNIX username and password upon the first launch. This user is independent of the Windows user and is only valid within WSL.&lt;/p>
&lt;p>If you are already using WSL1, convert it to WSL2 with the following command.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Convert an existing distribution to WSL2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-set-version&lt;/span> &lt;span class="n">Ubuntu&lt;/span> &lt;span class="mf">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Set WSL2 as the default version for any future distributions you add&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-set-default-version&lt;/span> &lt;span class="mf">2&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="4-the-secret-of-resource-control-wslconfig-and-wslconf">4. The Secret of Resource Control: .wslconfig and wsl.conf
&lt;/h2>&lt;p>One of the biggest traps in WSL2 is the &amp;ldquo;unlimited consumption of memory (bloating of the Vmmem process)&amp;rdquo;. Since WSL2 utilizes the Linux kernel&amp;rsquo;s page cache, it will endlessly consume the host&amp;rsquo;s (Windows) memory every time it performs I/O. To prevent this, it is essential to limit resources using configuration files.&lt;/p>
&lt;p>WSL2 configuration files are divided into two: &lt;strong>&lt;code>.wslconfig&lt;/code> which affects the entire Windows system&lt;/strong>, and &lt;strong>&lt;code>wsl.conf&lt;/code> which affects the inside of each distribution&lt;/strong>.&lt;/p>
&lt;h3 id="41-wslconfig-windows-side">4.1. .wslconfig (Windows side)
&lt;/h3>&lt;p>Create a file in the Windows user profile directory (&lt;code>C:\Users\&amp;lt;username&amp;gt;\.wslconfig&lt;/code>) to control resource allocation for the VM.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-ini" data-lang="ini">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># C:\Users\&amp;lt;username&amp;gt;\.wslconfig&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[wsl2]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Maximum memory allocated to the VM. We recommend about 50% to 75% of the host&amp;#39;s total memory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">memory&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">16GB&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Number of CPU cores to use (uses all cores if omitted)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">processors&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">8&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Size of the swap file&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">swap&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">8GB&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Destination to save the swap file (useful if you want to save space on the C drive)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># swapfile=D:\\wsl\\swap.vhdx&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Enable localhost forwarding (to access WSL from the Windows side using localhost)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">localhostForwarding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Automatically free up memory (Windows 11 only)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Dynamically releases page cache to prevent Vmmem bloating&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">autoMemoryReclaim&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">dropcache&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[experimental]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Advanced networking features available in Windows 11 22H2 and later&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># This enables IPv6 support and allows sharing the same IP address between WSL and Windows&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">networkingMode&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">mirrored&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">dnsTunneling&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">firewall&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">autoProxy&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="42-wslconf-linux-side">4.2. wsl.conf (Linux side)
&lt;/h3>&lt;p>Edit &lt;code>/etc/wsl.conf&lt;/code> inside WSL to control the distribution-specific behavior.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-ini" data-lang="ini">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># /etc/wsl.conf (edit inside WSL)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[network]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Disable the automatic generation of /etc/resolv.conf when WSL starts&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Useful when you want to set your own DNS (e.g., 8.8.8.8)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">generateResolvConf&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">false&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Set a custom hostname&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">hostname&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">WSL-DevNode&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[automount]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Settings for mounting Windows drives&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">enabled&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">options&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;metadata,uid=1000,gid=1000,umask=022&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Change the mount point of the C drive from /mnt/c to /c (to shorten the path)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">root&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[boot]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Enable systemd (WSL 0.67.6 or later)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># This allows snaps and various daemons (like Docker) to run natively&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">systemd&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">[user]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Default user to log in as&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">default&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">kenji&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>To apply these settings, you need to run &lt;code>wsl --shutdown&lt;/code> in PowerShell to completely stop the WSL VM and then restart it.&lt;/p>
&lt;hr>
&lt;h2 id="5-the-ultimate-terminal-environment-zsh--powerlevel10k">5. The Ultimate Terminal Environment: Zsh + Powerlevel10k
&lt;/h2>&lt;p>Productivity won&amp;rsquo;t improve if you stick with the default bash. Combine Zsh, which boasts powerful completion features and visibility, with the ultra-fast theme &amp;ldquo;Powerlevel10k&amp;rdquo; to build the strongest prompt.&lt;/p>
&lt;h3 id="51-installing-and-configuring-windows-terminal">5.1. Installing and Configuring Windows Terminal
&lt;/h3>&lt;p>Install &amp;ldquo;Windows Terminal&amp;rdquo; from the Microsoft Store. Open the JSON settings (&lt;code>settings.json&lt;/code>), set the default profile to WSL (Ubuntu), and change the font to a Nerd Font for development (e.g., &lt;code>HackGen Console NF&lt;/code> or &lt;code>MesloLGS NF&lt;/code>).&lt;/p>
&lt;h3 id="52-installing-zsh-and-oh-my-zsh">5.2. Installing Zsh and Oh My Zsh
&lt;/h3>&lt;p>Run the following commands in the WSL terminal.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Update packages and install Zsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo apt update &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> sudo apt upgrade -y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo apt install -y zsh git curl
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Run the Oh My Zsh installation script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sh -c &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="k">$(&lt;/span>curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="53-introducing-powerlevel10k-and-plugins">5.3. Introducing Powerlevel10k and Plugins
&lt;/h3>&lt;p>Introduce plugins that further enhance Zsh (syntax highlighting and auto-suggestions) and the Powerlevel10k theme.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Powerlevel10k&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git clone --depth&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span> https://github.com/romkatv/powerlevel10k.git &lt;span class="si">${&lt;/span>&lt;span class="nv">ZSH_CUSTOM&lt;/span>&lt;span class="k">:-&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="p">/.oh-my-zsh/custom&lt;/span>&lt;span class="si">}&lt;/span>/themes/powerlevel10k
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># zsh-autosuggestions&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git clone https://github.com/zsh-users/zsh-autosuggestions &lt;span class="si">${&lt;/span>&lt;span class="nv">ZSH_CUSTOM&lt;/span>&lt;span class="k">:-&lt;/span>&lt;span class="p">~/.oh-my-zsh/custom&lt;/span>&lt;span class="si">}&lt;/span>/plugins/zsh-autosuggestions
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># zsh-syntax-highlighting&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git clone https://github.com/zsh-users/zsh-syntax-highlighting.git &lt;span class="si">${&lt;/span>&lt;span class="nv">ZSH_CUSTOM&lt;/span>&lt;span class="k">:-&lt;/span>&lt;span class="p">~/.oh-my-zsh/custom&lt;/span>&lt;span class="si">}&lt;/span>/plugins/zsh-syntax-highlighting
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Edit &lt;code>~/.zshrc&lt;/code> to enable the theme and plugins.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Changes in ~/.zshrc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ZSH_THEME&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;powerlevel10k/powerlevel10k&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add to the plugins array&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">plugins&lt;/span>&lt;span class="o">=(&lt;/span>git zsh-autosuggestions zsh-syntax-highlighting&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>After saving, running &lt;code>source ~/.zshrc&lt;/code> will launch the Powerlevel10k configuration wizard (&lt;code>p10k configure&lt;/code>). Follow the on-screen instructions to customize the prompt to your liking (prompt style, presence of icons, information to display, etc.). Information such as the Git branch name and status, Node.js version, and command execution time will be displayed in real-time, dramatically improving your development efficiency.&lt;/p>
&lt;hr>
&lt;h2 id="6-seamless-integration-with-vs-code-remote---wsl">6. Seamless Integration with VS Code Remote - WSL
&lt;/h2>&lt;p>For development in WSL2, the &amp;ldquo;Remote - WSL&amp;rdquo; extension is the mechanism that seamlessly accesses files inside WSL from the IDE (Visual Studio Code) installed on the Windows side.&lt;/p>
&lt;h3 id="architecture-explanation">Architecture Explanation
&lt;/h3>&lt;p>The following sequence diagram shows how VS Code communicates with WSL2.&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
autonumber
participant U as &amp;#34;Developer&amp;#34;
participant V as &amp;#34;VS Code UI (Windows)&amp;#34;
participant S as &amp;#34;VS Code Server (WSL2)&amp;#34;
participant F as &amp;#34;ext4 File System (WSL2)&amp;#34;
U-&amp;gt;&amp;gt;V: &amp;#34;Type `code .` in WSL Terminal&amp;#34;
V-&amp;gt;&amp;gt;S: &amp;#34;Establish RPC Connection via Vsock&amp;#34;
Note over V,S: Communicates via Hyper-V sockets without using TCP/IP
S-&amp;gt;&amp;gt;F: &amp;#34;Read Source Files / Run Linter&amp;#34;
F--&amp;gt;&amp;gt;S: &amp;#34;Return Data &amp;amp; Analysis&amp;#34;
S--&amp;gt;&amp;gt;V: &amp;#34;Stream Language Server results to UI&amp;#34;
V--&amp;gt;&amp;gt;U: &amp;#34;Display syntax highlighting &amp;amp; errors&amp;#34;
&lt;/pre>
&lt;p>The VS Code on the Windows side acts merely as a &amp;ldquo;thin client (UI)&amp;rdquo;, and heavy processing such as the Language Server, debugger, and terminal execution are all handled by the &amp;ldquo;VS Code Server&amp;rdquo; on the WSL side. This allows you to keep your environment clean on the WSL side without installing Node.js or Python on the Windows side.&lt;/p>
&lt;h3 id="essential-vs-code-settings">Essential VS Code Settings
&lt;/h3>&lt;p>Install &lt;strong>&amp;ldquo;WSL&amp;rdquo; (ms-vscode-remote.remote-wsl)&lt;/strong> from the &amp;ldquo;Extensions&amp;rdquo; in VS Code. After that, simply navigate to your project directory in the WSL terminal and run &lt;code>code .&lt;/code>, which will launch the Windows-side VS Code with that directory open.&lt;/p>
&lt;p>&lt;strong>Important Note (Line Ending Issue):&lt;/strong>
Windows and Linux have different line endings (Windows uses &lt;code>CRLF&lt;/code>, while Linux uses &lt;code>LF&lt;/code>). When developing on WSL, be sure to unify Git&amp;rsquo;s &lt;code>core.autocrlf&lt;/code> setting and VS Code&amp;rsquo;s default file setting to &lt;code>LF&lt;/code>. Neglecting this will cause you to suffer from mysterious errors when executing shell scripts or Docker containers.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Git line ending setting on the WSL side&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git config --global core.autocrlf input
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Also add the following to VS Code&amp;rsquo;s &lt;code>settings.json&lt;/code> (remote settings).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;files.eol&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;\n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;terminal.integrated.defaultProfile.linux&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;zsh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-optimizing-docker-desktop-and-wsl2-integration">7. Optimizing Docker Desktop and WSL2 Integration
&lt;/h2>&lt;p>There are mainly two approaches to using Docker in a WSL2 environment:&lt;/p>
&lt;ol>
&lt;li>Install &lt;strong>Docker Desktop for Windows&lt;/strong> and enable the WSL2 integration feature.&lt;/li>
&lt;li>Directly install &lt;strong>native Docker Engine&lt;/strong> inside WSL2 (e.g., Ubuntu).&lt;/li>
&lt;/ol>
&lt;h3 id="approach-1-docker-desktop-recommended">Approach 1: Docker Desktop (Recommended)
&lt;/h3>&lt;p>This is recommended in most cases because it is easy to manage via a GUI and allows transparent access to containers between Windows and WSL. Check the following in the Docker Desktop settings (Settings):&lt;/p>
&lt;ul>
&lt;li>Check &lt;code>General&lt;/code> -&amp;gt; &lt;code>Use the WSL 2 based engine&lt;/code>.&lt;/li>
&lt;li>Check &lt;code>Resources&lt;/code> -&amp;gt; &lt;code>WSL Integration&lt;/code> -&amp;gt; &lt;code>Enable integration with my default WSL distro&lt;/code>, and turn on the toggle button for the distribution you use (Ubuntu).&lt;/li>
&lt;/ul>
&lt;p>This allows you to execute the &lt;code>docker&lt;/code> command directly from the WSL2 terminal, and communication with the Docker daemon is done through dedicated lightweight VMs (&lt;code>docker-desktop&lt;/code> and &lt;code>docker-desktop-data&lt;/code>) managed by Docker Desktop.&lt;/p>
&lt;h3 id="approach-2-direct-installation-of-native-docker-engine">Approach 2: Direct Installation of Native Docker Engine
&lt;/h3>&lt;p>If there are corporate network restrictions (like avoiding paid Docker Desktop plans) or if you want to minimize performance overhead to the limit, enable &lt;code>systemd&lt;/code> in &lt;code>/etc/wsl.conf&lt;/code> and install Docker as a pure Ubuntu server.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Excerpt of the official Docker installation steps on WSL2 Ubuntu with systemd enabled&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo apt-get update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo apt-get install ca-certificates curl gnupg
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo install -m &lt;span class="m">0755&lt;/span> -d /etc/apt/keyrings
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -fsSL https://download.docker.com/linux/ubuntu/gpg &lt;span class="p">|&lt;/span> sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo chmod a+r /etc/apt/keyrings/docker.gpg
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add repository&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="s2">&amp;#34;deb [arch=&amp;#34;&lt;/span>&lt;span class="k">$(&lt;/span>dpkg --print-architecture&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34; signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&lt;/span>&lt;span class="k">$(&lt;/span>. /etc/os-release &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$VERSION_CODENAME&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34; stable&amp;#34;&lt;/span> &lt;span class="p">|&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo apt-get update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add the current user to the docker group (to execute without sudo)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo usermod -aG docker &lt;span class="nv">$USER&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>After a reboot, &lt;code>systemctl start docker&lt;/code> will function exactly like a native Linux environment and deliver high performance.&lt;/p>
&lt;hr>
&lt;h2 id="8-ssh-key-integration-seamless-authentication-between-windows-and-wsl">8. SSH Key Integration: Seamless Authentication between Windows and WSL
&lt;/h2>&lt;p>Managing separate SSH keys on the Windows side and the WSL side when doing Git SSH cloning or SSH connecting to remote servers is extremely tedious. To balance security and convenience, configure a bridge for the SSH agent running on the Windows side (or a password manager like 1Password) to the WSL side.&lt;/p>
&lt;p>Here, we will explain the most secure and modern approach: using the &lt;strong>1Password SSH Agent feature&lt;/strong> or the &lt;strong>Windows OpenSSH Authentication Agent&lt;/strong>, and forwarding it to a UNIX domain socket in WSL2 using &lt;code>npiperelay&lt;/code> or &lt;code>socat&lt;/code>.&lt;/p>
&lt;h3 id="socket-forwarding-for-ssh-agent">Socket Forwarding for ssh-agent
&lt;/h3>&lt;p>You need to convert the SSH agent typically provided as a Named Pipe in Windows into a socket file on the WSL side. This is easy if you use &lt;code>wsl-ssh-agent&lt;/code> or the features provided by 1Password.&lt;/p>
&lt;p>From the 1Password settings screen, enable &amp;ldquo;Developer&amp;rdquo; -&amp;gt; &amp;ldquo;Use SSH agent&amp;rdquo;.
Next, add the following configuration to &lt;code>~/.zshrc&lt;/code> or &lt;code>~/.bashrc&lt;/code> on the WSL side so that it automatically binds to the socket upon login.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Addition to ~/.zshrc (Example when using 1Password SSH Agent)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">SSH_AUTH_SOCK&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nv">$HOME&lt;/span>/.ssh/agent.sock
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># If the socket doesn&amp;#39;t exist at WSL startup, or the process isn&amp;#39;t bound, forward using socat and npiperelay&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ALREADY_RUNNING&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="k">$(&lt;/span>ps -aux &lt;span class="p">|&lt;/span> grep &lt;span class="s2">&amp;#34;[n]piperelay.exe -ei -s //./pipe/openssh-ssh-agent&amp;#34;&lt;/span> &lt;span class="p">|&lt;/span> wc -l&lt;span class="k">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="o">[&lt;/span> &lt;span class="nv">$ALREADY_RUNNING&lt;/span> -eq &lt;span class="m">0&lt;/span> &lt;span class="o">]&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">then&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="o">[&lt;/span> -S &lt;span class="nv">$SSH_AUTH_SOCK&lt;/span> &lt;span class="o">]&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">then&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> rm &lt;span class="nv">$SSH_AUTH_SOCK&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Launch socat in the background to connect the Windows-side Named Pipe to the WSL-side UNIX socket&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">(&lt;/span>setsid socat UNIX-LISTEN:&lt;span class="nv">$SSH_AUTH_SOCK&lt;/span>,fork EXEC:&lt;span class="s2">&amp;#34;npiperelay.exe -ei -s //./pipe/openssh-ssh-agent&amp;#34;&lt;/span>,nofork &lt;span class="p">&amp;amp;&lt;/span>&lt;span class="o">)&lt;/span> &amp;gt;/dev/null 2&amp;gt;&lt;span class="p">&amp;amp;&lt;/span>&lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">fi&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;em>Note: You must install &lt;code>npiperelay.exe&lt;/code> on the Windows side and add it to your PATH beforehand.&lt;/em>&lt;/p>
&lt;p>Once this setup is complete, when you run &lt;code>ssh-add -l&lt;/code> from the WSL terminal, a list of public keys for the SSH keys registered in 1Password or on the Windows side will be displayed. This allows you to securely pass authentication without copying your private key files into WSL.&lt;/p>
&lt;hr>
&lt;h2 id="9-maintenance-optimizing-compacting-the-bloated-vhdx">9. Maintenance: Optimizing (Compacting) the Bloated VHDX
&lt;/h2>&lt;p>One of the biggest drawbacks of WSL2 is its behavior where &amp;ldquo;the file size of the virtual disk (.vhdx) on the Windows side is not automatically reduced even when Docker images or files are deleted&amp;rdquo;. If you continue developing for a long time, the ext4.vhdx file will swell to tens or hundreds of gigabytes.&lt;/p>
&lt;p>To free up disk space, you need to regularly optimize (Compact) the VHDX from the Windows side.&lt;/p>
&lt;ol>
&lt;li>First, completely shut down WSL.
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-shutdown&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>Open PowerShell with administrator privileges and run the following &lt;code>diskpart&lt;/code> command, or the &lt;code>Optimize-VHD&lt;/code> command of the Hyper-V module (the latter can only be used if Hyper-V is enabled).&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># When the Hyper-V module is available&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Optimize-VHD&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$env:LOCALAPPDATA&lt;/span>&lt;span class="s2">\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx&amp;#34;&lt;/span> &lt;span class="n">-Mode&lt;/span> &lt;span class="n">Full&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># When using diskpart&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">diskpart&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Enter interactively in the following prompt&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">DISKPART&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="nb">select &lt;/span>&lt;span class="n">vdisk&lt;/span> &lt;span class="n">file&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="s2">&amp;#34;C:\Users\&amp;lt;username&amp;gt;\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">DISKPART&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">attach&lt;/span> &lt;span class="n">vdisk&lt;/span> &lt;span class="n">readonly&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">DISKPART&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">compact&lt;/span> &lt;span class="n">vdisk&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">DISKPART&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">detach&lt;/span> &lt;span class="n">vdisk&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">DISKPART&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">exit&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>By performing this operation regularly, you can reclaim unnecessarily consumed space on your C drive.&lt;/p>
&lt;hr>
&lt;h2 id="10-conclusion">10. Conclusion
&lt;/h2>&lt;p>WSL2 has completely transcended the framework of being just a &amp;ldquo;bonus Linux running on Windows&amp;rdquo; and has evolved into a powerful development platform that is equal to, or even better than, MacOS and native Linux machines.&lt;/p>
&lt;p>By applying all the configurations explained here (resource optimization via &lt;code>.wslconfig&lt;/code>, terminal enhancement with Zsh + Powerlevel10k, transparent access with VS Code Remote, and SSH integration and VHDX maintenance), a stress-free, fast, and secure &amp;ldquo;ultimate development environment&amp;rdquo; is completed.&lt;/p>
&lt;p>Although setting up the environment takes a little effort, once the settings are solidified, there is no doubt that your future engineering productivity will improve dramatically. Please explore further customizations based on this guide to suit your projects and preferences.&lt;/p></description></item></channel></rss>