The Software

Chapter 12 — Software Setup

The hardware is installed, BIOS is configured, XMP is enabled. This chapter covers the software side: installing Windows 11 cleanly on the new NVMe, getting drivers in the right order, setting up WSL2 and Docker with sensible memory limits, organising the three drives, and running the benchmarks that confirm everything is working as expected — including a side-by-side comparison with the old i5-10400 machine.

Windows 11 — Clean Install on the NVMe

Why a clean install rather than migrating: The old system ran an LGA1200 chipset. Migrating a Windows install to a completely different platform causes driver conflicts, lingering INF files for the old chipset, and bloat from the old machine's software. A clean install on the new NVMe takes 20 minutes and starts the new machine in a known-good state. The Samsung 870 EVO and WD Blue already hold your data — they can be reconnected without any data loss.
1
Create Windows 11 installation USB (on another machine)
Download Rufus (rufus.ie — free, no install needed) and the Windows 11 ISO from microsoft.com/software-download/windows11. Use an 8GB+ USB drive. In Rufus: select the ISO, partition scheme = GPT, target system = UEFI (non-CSM), file system = NTFS. Click Start. This takes 5–10 minutes.
Rufus also lets you create a "Windows 11 without TPM/Secure Boot check" USB — useful for testing on unsupported hardware, but not needed here since you've configured TPM and Secure Boot in BIOS correctly.
2
Disconnect the Samsung 870 EVO and WD Blue (temporarily)
Before booting the installer: unplug the SATA data cables from both 2.5" drives. This prevents the Windows installer from accidentally writing a boot sector to the wrong drive. The NVMe is the only target. Reconnect the SATA drives after Windows is installed and running.
The Windows installer has a "Delete Partition / Format" step that is easy to apply to the wrong drive when multiple drives are visible. Disconnecting SATA drives eliminates this risk entirely.
3
Boot from the USB drive
Plug the USB drive in and reboot. Press F11 (MSI) or F8 (ASUS) during POST to open the one-time boot menu — select the USB drive. The Windows installer loads. If the boot menu doesn't appear, enter BIOS (Del/F2) and temporarily set the USB as the first boot device.
4
Install: language, edition, partition
Select: Language = English (UK), Time = GMT, Keyboard = United Kingdom. Choose Windows 11 Pro (not Home) — Pro includes Hyper-V, Remote Desktop Server, BitLocker, and Group Policy editor, all useful for dev work. When asked about type of installation, choose Custom: Install Windows only (advanced). Select the NVMe drive, delete any existing partitions on it, then click New to let Windows create fresh GPT partitions automatically. Click Next.
Windows 11 Pro and Home use the same installer ISO — the edition choice appears on the second screen. If you have a Windows 10 Pro key from the old machine, it will activate Windows 11 Pro automatically via Microsoft's digital licence system (tied to your Microsoft account).
5
Setup: account type and privacy settings
During the out-of-box experience (OOBE): choose Set up for personal use. For account: use a local account rather than a Microsoft account for a dev machine (less telemetry, no OneDrive sync pressure). To force local account: when asked to sign in, choose "Sign in options" → "Offline account" → "Limited experience". Set a strong password. On the privacy screens, disable all optional diagnostics, advertising ID, and location.
If you skip the local account option and sign in with a Microsoft account, your username folder becomes your Microsoft account email prefix (e.g. C:\Users\philipo) — this can cause path issues in some dev tools. A local account gives you a clean username.
6
Reconnect SATA drives and initialise in Disk Management
Once Windows is running: shut down, reconnect the SATA data cables to the Samsung 870 EVO and WD Blue, reboot. Open Disk Management (Win+R → diskmgmt.msc). Both drives appear as "Not Initialized" — right-click each, choose Initialize Disk → GPT. Then right-click the unallocated space on each → New Simple Volume → assign drive letters D: (870 EVO) and E: (WD Blue). Format NTFS with default allocation unit size.

Driver Installation — Order Matters

Windows 11 automatically installs generic drivers for most devices during setup, but generic drivers are not the same as manufacturer-optimised drivers. Install in this order — the chipset must go first because every other driver is mapped to devices it exposes:

1
Intel Chipset Driver
Sourceintel.com/download → search "B760 chipset"
What it installsINF files for all B760 PCIe/USB/SATA controllers
Reboot requiredYes
Install this before anything else. It doesn't install visible software — it maps the underlying hardware to Windows. Every subsequent driver installs on top of this correctly-mapped foundation.
2
Intel ME (Management Engine)
Sourceintel.com/download → "Intel ME driver"
What it installsIntel ME Interface, out-of-band management
Reboot requiredYes
Without this, Device Manager shows a yellow "Unknown device" for the Intel Management Engine. Also enables Intel PTT (fTPM) to function correctly under Windows and fixes some sleep/wake issues.
3
NVIDIA GPU Driver
Sourcenvidia.com/drivers → RTX 3050, GeForce 30 Series
Install typeCustom → Clean Install
Reboot requiredYes
Choose "Custom Install" and tick "Perform a clean installation" to wipe the generic Microsoft display driver. This is when hardware video decode, NVENC, and proper power management (fan-stop at idle) activate.
4
Network / WiFi Driver
SourceBoard manufacturer's support page
MSI TOMAHAWKIntel I225-V LAN + Intel WiFi 6E AX211
Reboot requiredYes
The Intel I225-V 2.5GbE driver matters for network throughput — the generic driver limits to 1GbE. After installing, Device Manager should show "Intel(R) Ethernet Controller (3) I225-V" at 2500 Mbps.
5
Realtek Audio
SourceBoard manufacturer's support page
What it installsHD Audio + Realtek Audio Console app
Reboot requiredSometimes
Skip if you use USB or Bluetooth audio exclusively. If using the board's 3.5mm rear audio jacks, install this. The Realtek Console app allows front/rear jack switching and virtual surround configuration.
6
Remaining: Windows Update
RunSettings → Windows Update → Advanced → Optional Updates
Also runWindows Update → Check for updates (all)
RebootAfter all updates applied
Windows Update delivers Intel storage, USB controller, and Bluetooth drivers via Optional Updates. Install everything offered. After this pass, Device Manager should show zero yellow exclamation marks.

WSL2 Setup & Configuration

WSL2 (Windows Subsystem for Linux v2) is the foundation for Docker Desktop on this machine and your primary Linux environment for dev work. Install and configure it before Docker.

# Run in Windows Terminal (or PowerShell as Administrator) # Install WSL2 with Ubuntu (default distro) wsl --install # After reboot — verify WSL version wsl --list --verbose # Should show: NAME STATE VERSION # Ubuntu Running 2 # Ensure future distros default to WSL2 wsl --set-default-version 2

Critical: Configure WSL2 Memory Limits

By default, WSL2 can consume up to 50% of system RAM (up to 32GB on a 64GB machine). This is too aggressive for a dev machine where Windows, Docker, and the IDE also need memory. Create a .wslconfig file in your Windows home directory to cap it:

# Create this file at: C:\Users\YourUsername\.wslconfig # Open Notepad and save to that exact path, or run: notepad $env:USERPROFILE\.wslconfig # Contents of .wslconfig: [wsl2] memory=16GB # WSL2 max RAM (leaves 48GB for Windows + apps) processors=12 # CPU threads for WSL2 (leaves cores for Windows) swap=4GB # WSL2 swap file size localhostForwarding=true # localhost in Windows reaches WSL2 services # After saving, restart WSL2: wsl --shutdown wsl
Why 16GB and not more? With 64GB total RAM: 16GB for WSL2 leaves 48GB for Windows, Docker, the IDE, Chrome, and active compile jobs. WSL2 only uses RAM it actually needs — the limit is a ceiling, not a reservation. If you regularly run memory-heavy workloads inside Linux (large databases, ML data pipelines), raise it to 24GB. The remaining 40GB is plenty for the Windows side.
# Inside WSL2 Ubuntu — set up a minimal /etc/wsl.conf sudo nano /etc/wsl.conf # Add: [automount] options = "metadata" # Preserves Linux file permissions on Windows drives [interop] appendWindowsPath = false # Stops Windows PATH polluting WSL2 PATH (faster) [boot] systemd = true # Enables systemd inside WSL2 (Ubuntu 22.04+)

Docker Desktop — WSL2 Backend Configuration

1
Install Docker Desktop
Download Docker Desktop from docker.com. During install: ensure "Use WSL 2 instead of Hyper-V" is selected (it should be the default if WSL2 is already installed). After install, Docker Desktop starts and shows a tutorial — skip it.
2
Enable WSL2 integration for Ubuntu
Docker Desktop Settings → Resources → WSL Integration → tick "Enable integration with additional distros" → tick Ubuntu. Apply & Restart. This makes the docker command available inside your Ubuntu WSL2 terminal — you can run containers from either Windows Terminal or WSL2.
3
Move the Docker data root to the NVMe
By default, Docker stores all images, volumes, and containers at C:\Users\YourName\AppData\Local\Docker\wsl — which is on the NVMe (C:). This is correct and requires no change. However, the Docker disk image (a large .vhdx file that can grow to tens of GB) lives in that same location. Monitor C: drive space as you pull images and prune regularly.
Prune unused images periodically: docker system prune -a — removes stopped containers, dangling images, unused networks. Run this before any disk-full situation on C:.
4
Set Docker Desktop resource limits
Docker Desktop Settings → Resources → Advanced. Set: CPUs = 8 (leaving 8 for Windows), Memory = 12GB (within the 16GB WSL2 ceiling). These limits apply to the Docker VM — individual containers can be further constrained with --memory flags. Disk image size limit: 64GB is a reasonable starting point; expand later if needed.
# Verify Docker is working from both Windows PowerShell and WSL2: docker run --rm hello-world # Should print "Hello from Docker!" and exit docker run --rm -it ubuntu:22.04 bash # Opens an interactive Ubuntu container shell # Type 'exit' to leave # Check Docker context (confirms WSL2 backend is active): docker context ls # Should show: desktop-linux * (current)

Essential Dev Software — Install Order

SoftwareWhere to GetNotes
Windows TerminalMicrosoft Store → "Windows Terminal"Install first — much better than legacy PowerShell window. Set WSL2 Ubuntu as the default profile.
Git (Windows)git-scm.com → Git for WindowsInstall with "Git Credential Manager" enabled. Shares credential store with WSL2 git via git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/bin/git-credential-manager.exe" inside WSL2.
VS Codecode.visualstudio.comInstall the WSL extension immediately after. This lets VS Code run its server inside WSL2 while the UI stays on Windows — best of both worlds for Linux-based dev work.
Python (Windows side)python.org or Microsoft StoreAlso install Python inside WSL2 separately — the Windows and WSL2 installs don't share packages or virtual environments.
Node.jsInstall via nvm inside WSL2 rather than the Windows installer — avoids PATH conflicts between Windows and WSL2 node versions.
JDKAdoptium.net → Eclipse Temurin LTSIf doing Java dev. Temurin is free, open-source, and actively maintained. Install on Windows for IDE use and inside WSL2 for build tooling separately.
Samsung Magiciansamsung.com/semiconductor → MagicianMonitors 990 Pro and 870 EVO health, temperature, firmware version. Set 990 Pro to "High Performance" mode in Magician for maximum throughput.
CrystalDiskInfocrystalmark.infoIndependent SMART health monitoring for all drives. Runs in system tray, alerts on drive health changes. Free.
HWiNFO64hwinfo.comReal-time sensor monitoring — CPU per-core temps, VRM temps, RAM voltage, GPU temp, fan RPMs. The most comprehensive sensor tool available.

Storage Organisation — All Three Drives

RECOMMENDED DIRECTORY STRUCTURE C:\ (NVMe — speed-critical) Suggested size: 1–2TB NVMe ├── Windows, Program Files (OS standard) ├── Users\YourName\ │ ├── AppData\Local\Docker\wsl\ (Docker disk image — keep on NVMe) │ └── .wslconfig (WSL2 memory config) └── Dev\ (create this folder) ├── projects\ (active git repositories) ├── venvs\ (Python virtual environments) └── tools\ (local SDKs, binaries) D:\ (Samsung 870 EVO 2TB — capacity) Archives + large data ├── VMs\ (VirtualBox / VMware disk images) ├── Projects-Archive\ (completed/inactive repos) ├── Docker-exports\ (docker save/load tarballs) └── Media\ (large video files, datasets) E:\ (WD Blue SA510 1TB — personal) Personal + backup ├── Personal\ (documents, photos) ├── Downloads\ (move default download folder here) └── Backup\ (local backup of C:\Dev)
C:
NVMe Gen 4 (1–2TB) — speed-critical workloads
  • Windows 11 (system files, page file)
  • Installed applications and IDEs
  • Active git repositories (C:\Dev\projects)
  • Python venvs and Node modules
  • Docker disk image (.vhdx — auto-located here)
  • WSL2 virtual disk (/home filesystem)
  • Database files (Postgres, MySQL data dirs)
D:
Samsung 870 EVO 2TB — capacity storage
  • VirtualBox / VMware .vmdk disk images
  • Archived project repositories
  • Large datasets and media files
  • Docker image tarballs (docker save exports)
  • ISO files and installation media
  • Build artefacts and compiled binaries
E:
WD Blue SA510 1TB — personal + backup
  • Personal documents and photos
  • Browser downloads (move default folder here)
  • Local backup of C:\Dev (weekly robocopy)
  • Music and personal media
  • Scanned documents
# Move the Downloads folder to E:\ (run in PowerShell) # Right-click Downloads in Explorer → Properties → Location → Move → E:\Downloads # Or via shell — this creates a junction (symlink) so apps still find it: mkdir E:\Downloads robocopy "$env:USERPROFILE\Downloads" "E:\Downloads" /E /MOVE cmd /c mklink /J "$env:USERPROFILE\Downloads" "E:\Downloads" # Weekly local backup of active projects (run in PowerShell, or Task Scheduler): robocopy C:\Dev E:\Backup\Dev /E /MIR /XD .git node_modules __pycache__ /LOG:E:\Backup\backup.log # /MIR = mirror (deletes files in dest that are gone from source) # /XD = exclude these dirs (saves space — git history is already the backup)

Benchmarks — Confirming Everything Works

Run these benchmarks once the machine is fully set up. They serve two purposes: confirming the hardware is operating correctly, and giving you a reference baseline so future regressions (thermal throttling, RAM frequency drift) are detectable.

CrystalDiskMark 8
NVMe Sequential Speed
Seq Read (Q8T1)
7,000+ MB/s
Seq Write (Q8T1)
6,000+ MB/s
4K Random Read
70+ MB/s
SATA (870 EVO) Read
560 MB/s
Select the NVMe (C:) as the test drive. Expected for Samsung 990 Pro or equivalent Gen 4: 7,000–7,450 MB/s sequential read. If you see ~3,500 MB/s, the NVMe may be seated in a PCIe 3.0 slot or the PCIe Gen setting in BIOS needs checking.
AIDA64 Extreme — Memory Benchmark
DDR4-3600 Dual Channel Bandwidth
Memory Read
~54 GB/s
Memory Write
~50 GB/s
Memory Copy
~46 GB/s
Latency
~60–70 ns
Run: AIDA64 → Tools → Memory & Cache Benchmark → Start. Expected for DDR4-3600 dual channel (2×32GB A2+B2): ~50–55 GB/s read. If you see ~28 GB/s, the sticks are in single-channel (A1+A2 or B1+B2) — move to A2+B2. If you see ~30 GB/s dual channel, XMP may not have applied — re-check BIOS.
Cinebench R23
i7-13700K CPU Performance
Single Core
2,000+
Multi Core
30,000+
i5-10400 single (old)
~1,150
i5-10400 multi (old)
~9,000
Run the multi-core test 10 minutes after system is stable at idle (to avoid PL2 burst inflating the score). If multi-core score is below 25,000, the board may still be using MCE (PL1 = 253W) causing thermal throttle — re-check Chapter 11 power limit settings.

Old vs New — Performance Jump

i5-10400 (old) vs i7-13700K (new) — Expected Real-World Gains
Cinebench R23 Multi-Core (higher = better)
i5-10400
~9,000
i7-13700K
~31,000
Cinebench R23 Single-Core (IPC + clock speed)
i5-10400
~1,150
i7-13700K
~2,050
Large project compile (Maven/Gradle — more cores = faster)
i5-10400
~100%
i7-13700K
~3.2× faster
Docker build (multi-stage, parallelised)
i5-10400
~100%
i7-13700K
~2.5–3× faster
NVMe sequential read (Gen 4 vs likely Gen 3 / SATA on old machine)
Old boot drive
~550 MB/s
NVMe Gen 4
7,400 MB/s
RAM bandwidth (DDR4-3600 DC vs DDR4-2666 or lower previously)
Estimated old
~35 GB/s
DDR4-3600 DC
~54 GB/s

Software Setup Completion Checklist

Windows 11 Pro activated: Settings → System → Activation. Should show "Windows is activated with a digital licence linked to your Microsoft account" (if using a transferred key) or prompt for product key entry. An unactivated machine has no functional limitations except the watermark — activate when convenient.
All drivers installed, no yellow flags in Device Manager: Right-click Start → Device Manager. No yellow exclamation marks anywhere. Check specifically: Network Adapters (Intel I225-V at 2.5GbE), Display Adapters (NVIDIA GeForce RTX 3050), System Devices (Intel Management Engine Interface).
WSL2 running Ubuntu with .wslconfig applied: Open Windows Terminal → Ubuntu profile. Run free -h — the total memory should reflect your .wslconfig memory= setting (e.g. ~15.5 GB for memory=16GB). Run nproc — should show the processor count you set.
Docker hello-world runs from both Windows and WSL2: In PowerShell: docker run --rm hello-world → success. In WSL2 terminal: same command → success. Both environments sharing the same Docker daemon confirms WSL2 integration is working.
Three drives accessible and correctly labelled: File Explorer shows C: (NVMe, ~OS size free), D: (Samsung 870 EVO, ~2TB), E: (WD Blue, ~1TB). CrystalDiskInfo shows all three with "Good" health status and correct drive model names. NVMe temperature under 50°C at idle.
CrystalDiskMark NVMe result above 6,500 MB/s sequential read: Anything below 5,000 MB/s on a Gen 4 drive is worth investigating (wrong slot, PCIe Gen setting in BIOS). SATA drives should read ~500–560 MB/s — both confirm the AHCI mode is applied correctly.
AIDA64 memory bandwidth above 48 GB/s: Read bandwidth between 50–56 GB/s confirms DDR4-3600 dual-channel is active. Bandwidth below 30 GB/s means either XMP is not applied or the sticks are in the wrong slots. Anything between 30–48 GB/s suggests one of the above issues partially applying.
Cinebench R23 multi-core above 27,000: The i7-13700K at PL1 (125W) should score 27,000–31,000. Significantly below 27,000 suggests thermal throttling (cooler mounting issue) or power limits set too conservatively. Above 35,000 suggests the board is running MCE/PL2 sustained — re-check power limits in BIOS.
Real dev workload test: Clone a medium-to-large project you work with regularly and run a full build. Note the time. This becomes your personal baseline — future builds should be within 10% of this figure. Any significant regression (slow compile, stuttering during Docker builds) can be investigated against this baseline.
Next: Type PC13 to generate the final chapter — Course Summary & What's Next, covering the complete parts list with final costs, a build retrospective comparing old vs new specs, the upgrade roadmap (case, RAM, GPU, PSU upgrade thresholds), and a maintenance schedule (thermal paste replacement, dust cleaning, drive health checks).