A web GUI that exposes how your AMD Ryzen Windows PC's PCIe lanes are allocated: which devices use which lanes, at what link width and speed, and how much of your CPU's lane budget is left.
Linux sibling: pizzy00/probi — same idea, native Linux build using
lspci+/sys/bus/pci. Laney is the Windows-native counterpart that uses the WinRing0 kernel driver to read the PCIe Capability registers Windows otherwise hides.
Windows tells you which PCIe devices are installed but not how they're wired: negotiated link width, current speed vs max, ASPM state, whether your GPU is sharing lanes with an M.2 slot. You currently have to piece that together from BIOS, GPU-Z, HWiNFO64, and the motherboard manual.
Laney reads the PCI Express Capability registers directly and shows the whole picture on one page that auto-refreshes every 5 seconds.
WSL2 runs in a Hyper-V VM and only sees a virtualized PCI bus. It can't see real link widths, ASPM state, or chipset routing. Laney has to be Windows-native — the Linux build (probi) belongs on a real Linux box.
- Platform card — detected CPU + chipset (AM4/AM5), total lane budget, chipset uplink speed.
- CPU lane bar — visual showing how many of your CPU's 24 (AM4) or 28 (AM5) lanes are allocated, plus a per-device table.
- Chipset uplink — devices hanging off the chipset and a saturation estimate (peak downstream bandwidth vs uplink width).
- Warnings — auto-flagged: GPU not at full x16, NVMe negotiated below max gen, ASPM enabled on storage (latency risk), and friends.
AMD AM4 (Zen 2 / Zen 3) and AM5 (Zen 4 / Zen 5) consumer platforms with chipsets X470/B450, X570, B550, X670E, X670, B650E, B650, A620.
Intel and Threadripper/EPYC are out of scope for v1; the architecture supports them — only src/laney/platforms.py needs extending.
You need three external files this repo deliberately does not ship:
| File | Where it goes | Source |
|---|---|---|
WinRing0x64.dll + WinRing0x64.sys |
drivers/ |
See drivers/README.md |
nssm.exe |
service/ |
https://nssm.cc/download |
htmx.min.js |
src/laney/static/ |
https://github.com/bigskysoftware/htmx/releases |
Then, from an elevated PowerShell:
git clone https://github.com/pizzy00/Laney.git
cd Laney\service
Set-ExecutionPolicy -Scope Process Bypass
.\install_service.ps1The installer prints both the loopback and LAN URLs once the service is
running. Default bind is 0.0.0.0:8765. Pass -BindHost 127.0.0.1 to
keep it local-only.
cd Laney\service
.\uninstall_service.ps1git clone https://github.com/pizzy00/Laney.git
cd Laney
pip install -r requirements.txt
$env:PYTHONPATH = "src"
python -m laney.flask_app --debugThe driver still has to be loaded — install once via any tool that ships WinRing0 (HWiNFO, OpenHardwareMonitor) and Laney will find the DLL automatically.
The pure-logic modules (pci_config, lane_model, platforms) have unit
tests with synthetic device topologies, so the lane-counting logic can be
verified without hardware:
python -m pytest tests/ -v24 tests cover register parsing, downgraded-link detection, ASPM warnings, chipset uplink saturation, bifurcated x8/x8 GPU, etc.
Laney/
src/laney/
pci_config.py # bit-level PCIe Capability register parsing (pure)
platforms.py # AM4/AM5 chipset table + CPUID decode (pure)
lane_model.py # allocation + warnings logic (pure)
winring0.py # ctypes wrapper for WinRing0x64.dll (Windows only)
hw_probe.py # PCI walk + PnP friendly names (Windows only)
flask_app.py # web GUI entry point
templates/ # Jinja
static/ # CSS + htmx (vendored, you supply the file)
service/ # NSSM-based Windows Service install
drivers/ # WinRing0 (you supply, not redistributed here)
tests/ # pytest fixtures, no hardware needed
- Default bind is
0.0.0.0:8765so the page is reachable on your trusted LAN — same as the Linux sibling. No auth. Fine on a home / lab network, don't expose to the public internet. Use-BindHost 127.0.0.1to lock it back down to loopback only. - No telemetry, no auto-update, no internet calls at runtime.
- WinRing0 is bound for read paths only (
ReadPciConfigDwordEx). The write functions are deliberately not bound in src/laney/winring0.py.
- Per-motherboard slot-share rules ("populating M.2_3 disables SATA 5/6"). Negotiated link width still surfaces when sharing has kicked in (a slot drops from x16 to x8) — you just don't get a board-specific explanation. Per-board YAML profiles can be added later.
- Intel and HEDT/server platforms.
- LAN auth / multi-user.
MIT — see LICENSE. WinRing0 is a separate project under its own permissive license; binaries are not redistributed in this repo.