| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| CHANGELOG.md | 2026-05-20 | 97.6 kB | |
| README.md | 2026-05-20 | 56.2 kB | |
| StressLab.exe | 2026-05-20 | 32.5 MB | |
| stresslab.py | 2026-05-19 | 744.5 kB | |
| QUICKSTART.md | 2026-05-15 | 17.3 kB | |
| LICENSE | 2026-04-28 | 1.1 kB | |
| THIRD_PARTY_LICENSES | 2026-04-28 | 9.0 kB | |
| requirements.txt | 2026-02-24 | 71 Bytes | |
| Totals: 8 Items | 33.4 MB | 111 |
StressLab v12.12.2
Internal Hardware Testing Suite for Windows
StressLab is an all-in-one hardware stress testing, diagnostics, and Windows repair tool built for PC builders, repair shops, and QA workflows. It runs sequential stress tests across CPU, RAM, GPU, VRAM, and Disk, with live temperature monitoring, deep SMART diagnostics, SMART self-tests, Windows system repair (SFC/DISM), and one-click service resets.
What's new in v12.12.2
Fixes the multi-cycle "View detailed charts" bug: clicking the link from any cycle tab now opens the chart for that specific cycle (aggregate, cycle 1, cycle 2, etc.) instead of always showing the same chart. Root cause was two-fold: only one zoom panel was generated per test (the call site found only the first matching phase), and the modal HTML ID was keyed only on test name so all cycles' triggers pointed at the same target. Now generates one zoom panel per cycle plus an aggregate spanning the full window, with cycle-scoped IDs (zoom-cpu-agg, zoom-cpu-1, zoom-cpu-2, ...) and proper trigger/modal placement (triggers inside cycle tabs, modals outside so the CSS :target pattern still works on inactive tabs).
Pure Python change. Rebuild via build_exe.bat.
What's new in v12.12.1
Important upgrade fix. Found a long-standing bug where lhm_reader.exe was only deployed on first launch — subsequent StressLab upgrades silently kept running the old helper from LOCALAPPDATA. This means the sensor matcher fixes shipped in v12.11.2 / .3 / .4 may not have actually been running on machines that had previously run an earlier StressLab.
Now: a lhm_version.txt sidecar tracks which StressLab version deployed the current helper. Version mismatch forces redeploy. Same fix applied to PresentMon via size comparison.
If the AMD/Gigabyte CPU temp fixes haven't seemed to take effect on your test rig, this is probably why. Installing v12.12.1 will force a fresh helper deploy on first launch.
Pure Python change. Rebuild via build_exe.bat.
What's new in v12.12
Two capture-mode additions:
- Capture progress on overlay — when a capture is running, a
CAP: MM:SS/MM:SS NN%row appears at the top of the metrics overlay. Auto-appears on start, auto-disappears on stop. Updates at 1Hz with neutral/orange/green color tiers. - Captured target in report + CSV — capture polling samples the foreground process each second and records the most-common one as the "captured target." Surfaces in the HTML report header (e.g.
Captured target: Cyberpunk2077.exe (94% of capture)) and as a# captured_target:metadata comment at the top of both CSV files. Secondary apps (Discord, browser) shown when they held foreground for ≥10% of capture.
Pure Python — drop in the new stresslab.py and rebuild.
What's new in v12.11.4
Fixes an iGPU-only regression from v12.11.2. AMD Ryzen 7000/9000 iGPU-only systems (where the iGPU exposes only GPU VR SoC and no GPU Core) were getting a blank GPU temp display. Now uses a two-pass evaluation: non-core sensors are stashed as tentative iGPU readings during iteration, and promoted to the displayed GPU temp only if no discrete GPU contributed a real value. Daniel's bug fix is preserved (a discrete GPU still always wins over iGPU readings).
Tested against 10 GPU configurations including Intel iGPU only, AMD iGPU only, NVIDIA dGPU only, AMD RX dGPU only, and various mixed configurations. All pass.
Build note: C# helper changed (SensorReading.cs + SensorMatcher.cs). Rebuild lhm_reader.exe via helper\build.bat.
What's new in v12.11.3
Anti-cheat warning fires at the actual point of use, not at startup. The warning only appears when the user enables the overlay AND has at least one PresentMon-derived metric (FPS, EPS, GPU busy %, display latency, generated frame %) checked, OR when they toggle on a PresentMon metric while the overlay is showing. Sensor-only overlays don't trigger the warning at all — no ETW session is started.
If you accepted the warning in a previous version, the latch is still in %LOCALAPPDATA%\StressLab\config.json so you won't be re-prompted. To test the new flow from scratch, delete that file.
Pure Python change — drop in the new stresslab.py and rebuild.
What's new in v12.11.2
Sensor matching fixes for AMD Ryzen + Gigabyte motherboard systems:
- CPU temp on Ryzen 9 7900X + Gigabyte B650 was showing 40°C instead of the real 93°C. Three combined fixes: (1) tighter CCD-pattern matching so
L3 (CCD1)/(CCD2)cache sensors don't get picked up, (2) explicit blocklist forIOD Hotspotand L-cache prefixes so they never become the headline CPU temp, (3) WMI thermal-zone fallback now only engages when the helper isn't running at all (was masking the real problem with a wrong-looking ACPI motherboard sensor value). - GPU temp was showing iGPU's
GPU VR SoC(44°C) instead of the RTX 5080'sGPU Core(57°C). Added blocklist for non-core GPU temperatures (VR SoC, GPU SoC, VRM, Mainboard, PCB) so voltage-regulator sensors can never become the user-facing "GPU temp" regardless of discrete-vs-integrated logic. - Diagnostic warning when helper is alive for >10s without reporting CPU temp, suggesting the user run the sensor dump tool. Helps surface board-specific matching gaps that need attention.
Build note: this release touches both the C# helper (SensorMatcher.cs) AND Python. Rebuild lhm_reader.exe via helper\build.bat before rebuilding the main exe.
What's new in v12.11.1
Six fixes/additions:
- FPS no longer blinks — cached stale-value fallback handles PresentMon's batched stdout flushes (300ms gaps were causing the avg FPS row to flash between value and
--). - Capture report charts enlarged —
minmax(640px)andmin-height: 240pxfor readable detail. - New PresentMon metrics: GPU busy %, display latency (ms), generated frame % (from
--track_frame_typefor DLSS-FG / FSR-FG / AMD AFMF / Intel XeFG detection). All opt-in via the overlay picker. - Raw CSV export alongside HTML — slow-metric CSV (sensors at 1Hz) and per-frame CSV (PresentMon per-frame data). Ready for Excel / pandas / CapFrameX.
- FPS auto-enabled by default when PresentMon is detected. Anti-cheat warning shown once and persisted to
%LOCALAPPDATA%\StressLab\config.json. Enable button only appears when PresentMon isn't available. - Better EPS description in report — "What it measures" + "How to read it" (4 tier ranges) + inline assessment for the current capture.
What's new in v12.11
Errors per second (EPS) metric based on PresentMon's MsAnimationError column. Measures perceived stutter that frame time alone misses — see GamersNexus's article for background. Counts frames where animation-vs-display timing drift exceeds 1ms, divided by rolling window length.
- New "Errors/sec (anim. error)" overlay row, opt-in via the metric picker. Color tiers: green <1, orange 1-5, red ≥5.
- New Animation Error sub-section in capture reports showing total error frames, average EPS, and peak 1-second EPS.
What's new in v12.10.4
Three bug fixes from field testing:
- Overlay was a blank gray box since v12.10.1. A tuple passed to
tk.Frame(pady=...)was raising a TclError that broke the build mid-way, leaving an emptyToplevelon screen. Fixed. - FPS reading lagged the game's own counter by ~1500ms. Two causes: a 1s rolling window contributed ~500ms phase lag, and overlay-update cadence was only 1Hz so the FPS labels could be up to a full second stale on top of that. Now uses a 300ms window AND a separate 5Hz overlay refresh just for FPS. Lag now ~300-500ms, mostly bounded by ETW delivery latency (RTSS has the same constraint).
- Build script warning about "no PresentMon bundled" now actually shows which files ARE in
assets\(off-version filenames hint at the right fix) and warns that a residual deploy in LOCALAPPDATA could mask the issue on your dev machine.
What's new in v12.10.3
Hotfix: PresentMon validation was rejecting valid binaries. I assumed PresentMon was ~3 MB; the actual console app is ~411 KB. The 142 MB MSI on GitHub is a different (full GUI) thing we don't need.
Replaced the wrong-headed size threshold with proper PE magic-byte validation (MZ + PE header signature). Now correctly accepts any valid Windows exe regardless of size while still cleanly rejecting HTML error pages, empty/truncated downloads, ZIPs, etc.
The 411 KB file already in your assets/ folder is correct — just rebuild with v12.10.3.
What's new in v12.10.2
Diagnostic improvements + deploy target fix for PresentMon bundling.
- build_exe.bat now reports whether PresentMon was found in
assets/(prints size + filename if yes, big warning block + directory listing if no). The final BUILD SUCCESS line explicitly says "Bundled PresentMon" or "NO PresentMon bundled". - Deploy target moved from the exe directory to
%LOCALAPPDATA%\StressLab\presentmon\(matches LHM helper pattern, writable without admin, survives upgrades cleanly). - Runtime diagnostics expanded: failed bundle lookups now show the exact directory checked, the accepted filenames, and what files actually are in that directory — so "I put it there but it didn't work" becomes immediately debuggable.
What's new in v12.10.1
Hotfix: PresentMon now bundles directly with StressLab instead of downloading on first use. v12.10's download path was failing on some networks (corporate proxies, Cloudflare bot detection rejecting python-urllib User-Agent).
Setup: drop PresentMon-2.3.1-x64.exe from Intel's GitHub releases into the assets/ folder. StressLab deploys it silently on first FPS enable. Download fallback still exists for stripped distributions.
PyInstaller spec already updated to include it automatically when packaging.
What's new in v12.10
- FPS tracking via PresentMon — real per-game FPS, 1% low, and 0.1% low (CapFrameX convention). Bundled on-demand (~3MB MIT download from Intel's GitHub releases). Two targeting modes: auto-follows foreground game, or manual pick from process dropdown. Available in the overlay metric picker (opt-in, off by default), and included in capture reports with frametime chart and statistics.
- Anti-cheat note: PresentMon uses ETW (no DLL injection — same mechanism as Steam Overlay) but some kernel anti-cheat systems have at various points flagged ETW capture. First-run dialog warns users. Don't run FPS tracking with Valorant/competitive titles with kernel anti-cheat; most games are fine.
- Overlay UX: bottom padding fixed to look balanced, label column auto-widens to fit long labels like "GPU HS:" without truncation.
- Show Metrics Overlay button moved from Stress Tests page to Metrics Monitoring tab (next to Capture controls). Toggle text flips between Show/Hide to match state.
What's new in v12.9
New Metrics Monitoring tab. Foundation work for the FPS/PresentMon integration coming in v12.10.
- New tab with 12 always-on charts (CPU/GPU temps, utilization, power, clocks, GPU hotspot, GPU memory °C, VRM °C, SSD °C, fans). Charts only redraw when the tab is visible.
- Capture mode — pick a duration (1/5/15/30/60 min), hit Start, get a self-contained HTML capture report with stats table (peak/mean/p99 per metric), zoomable SVG charts, system info, and SHA-256 integrity stamp. Reports save to
Documents/StressLab Reports/. - Overlay metric picker on the new tab — checkbox grid for 14 available metrics. Toggling immediately rebuilds the overlay. Default selection unchanged (CPU/GPU util+temp, RAM, VRAM) so existing users see no difference unless they touch the picker.
- Dynamic overlay sizing — height auto-expands when more metrics are selected, capped at 90% of screen height.
- CaptureHistory is a separate class from MetricHistory, time-stamped per sample so reports have accurate wall-clock x-axes even when polls drift.
What's new in v12.8
- Overlay sizes bumped up. Small is now what Medium used to be (280×162, 11pt), Medium is now what Large used to be (340×200, 13pt), and Large is doubled to 680×400 with 26pt body font — appropriate for 4K displays or reading from across the room.
- Percent utilization color tiers. CPU%, GPU%, RAM%, and VRAM% now color-code: green < 50%, orange 50-89%, red ≥ 90%. Temperature color tiers (≥70°C yellow / ≥80°C amber / ≥90°C red) unchanged.
What's new in v12.7
- Overlay now stays on top of borderless-windowed games. The v12.6 overlay was getting buried when games took focus because they re-shuffle the topmost slot. Fixed via periodic
SetWindowPos(HWND_TOPMOST)reassertion every 1.5s (withSWP_NOACTIVATEso it doesn't steal focus), plus removing theWS_EX_TOOLWINDOWstyle which was competing with games' topmost claims on some configurations. If you still see the overlay buried behind a specific game, the game is likely using DXGI independent-flip or fullscreen optimizations — right-click the game's exe → Properties → Compatibility → check "Disable fullscreen optimizations" to force it into normal borderless windowed. - Configurable text size. Right-click → Size → Small / Medium / Large. Small (240×138, 9pt) for minimal footprint, Medium (280×162, 11pt) default, Large (340×200, 13pt) for 4K displays or reading from a distance.
- RAM and VRAM now show absolute MB/GB alongside percent. Each row shows e.g.
RAM: 7.2/16 GB 45%. RAM comes frompsutil.virtual_memory(). VRAM MB comes fromnvidia-smi memory.used/total(NVIDIA only; AMD/Intel still get percent but not MB). The existing GPU util background thread now does a single multi-field nvidia-smi query so util + memory come from one subprocess. - Right-click menu reorganized. Corner options under Position submenu, size options under Size submenu, Hide overlay at the bottom.
What's new in v12.6
- Metrics overlay — toggleable from the Stress Tests page (new "Overlay" checkbox next to Stop on fail and Auto-export). Small semi-transparent window in the top-right corner (right-click for other corners or to hide) showing CPU%, CPU°C, GPU%, GPU°C, RAM%, VRAM%. Updates 1Hz from the existing telemetry pipeline, color-codes temperatures (yellow ≥70°C, amber ≥80°C, red ≥90°C), sets
WS_EX_NOACTIVATEso clicks don't steal focus from foreground apps. Works over the desktop and borderless-windowed games; does NOT work over true fullscreen exclusive (those need a DirectX/Vulkan hook overlay like NVIDIA Overlay or MSI Afterburner+RTSS, out of scope for StressLab).
What's new in v12.5
- RAM passes counter now shows pattern-position progress — large-RAM systems can take 60-90+ seconds for a single full 10-pattern cycle, so the previous
Passes: 0display lingered far too long. The panel now readsPasses: 0 (8/10)showing the slowest worker is on pattern 8 of 10. Replaces misleading floor-div averaging withmin()across workers. - GPU thermal interface degradation detector — compares the GPU hotspot to GPU core temperature during the run. Sustained delta ≥25°C triggers an alert in the stress log and a red-bordered section in the report recommending repaste (with PTM7950 specifically called out, since it's a phase-change pad that doesn't pump out over time). 20-24°C delta gets a gentler yellow info note. Healthy cards (10-15°C delta) get no card.
- build.bat fixed — was showing "Common causes" troubleshooting after every build, even successful ones, because some .NET SDK versions return non-zero on harmless trim warnings. Canonical success check is now "did the exe get produced?" not dotnet's exit code.
What's new in v12.4
GPU memory temperature monitoring is now significantly more reliable. Requires rebuilding the C# helper (helper/build.bat). See CHANGELOG.md for details.
- Broader memory-junction name matching in
SensorMatcher.cs— covers all the variants NVIDIA, AMD, and Intel Arc expose across driver versions ("GPU Memory Junction", "Memory Junction", plain "Memory", "GPU Memory" etc.). Previously many cards reported a value but StressLab silently missed it. - 255°C sentinel filter for the known LHM upstream bug where RTX 5090 (and possibly other RTX 50 cards) report a sentinel value instead of the real temp. Anything ≥200°C is now rejected as a clearly-wrong reading.
- Discrete-over-integrated priority applied to memory temp too — iGPUs don't have separate VRAM, so any memory reading from an iGPU is meaningless or mis-labelled.
- Peak GPU hotspot and peak GPU memory now tracked across each run and shown as separate cards in the report's Peak Readings dashboard. Both are commonly the actual thermal bottleneck on modern cards (GDDR6X memory junction can hit 100-110°C while the core is only 75°C, and the hotspot is what AMD/NVIDIA's own thermal protection acts on).
- Two new charts in the per-test zoom modal: GPU HOTSPOT and GPU MEMORY, each on a 0-115°C scale so values approaching the GDDR6X throttle threshold are visible. Silently absent on cards that don't expose those sensors.
What's new in v12.3
Three field-reported bug fixes. Requires rebuilding the C# helper (helper/build.bat) since two of the three fixes are in the sensor reader. See CHANGELOG.md for full details.
- Power test phase truncation fixed on slow CPUs (Ryzen 1600 / similar). The chart's time axis now uses real phase timestamps when available, and the 1Hz sensor poll loop is drift-corrected so it catches up after slow iterations instead of permanently lagging behind. A 15-minute Power test now produces a 15-minute-wide phase band even when the CPU is saturated.
- Zen 4 CPU temp reading fixed. Ryzen 7000-series CPUs (7900X, etc.) expose CCD chiplet temperature sensors that read substantially lower than the actual die temperature — a known Zen 4 silicon quirk. The old code let any of those sensors win the headline CPU temp; now Tctl/Tdie/Package always take precedence over CCD readings within the same poll, regardless of LHM iteration order.
- Discrete GPU temp now wins over iGPU. On Ryzen 7000 + NVIDIA discrete systems (e.g. 7900X + RTX 5080), the integrated Radeon Graphics enumerated first through the AMD driver path, hiding the discrete card's real temp. New
IsIntegratedGpu()helper classifies GPUs by hardware name; discrete sensors always take priority. Same fix applied to GPU power, GPU hotspot, and GPU fan.
What's new in v12.2
Bug-fix release. See CHANGELOG.md for details.
- VRAM cumulative totals fixed — the
Total VRAM written/verifiedfigures were showing only the last 30-second window from memtest_vulkan, not the cumulative totals over the whole run. Per-window values are now properly accumulated, with de-duplication by iteration number to handle re-reads of the log file. - VRAM panel now updates smoothly between memtest_vulkan reports. The Written/Checked numbers use the last-known bandwidth to extrapolate forward so the panel doesn't appear frozen for 30+ seconds at a time during the steady-state portion of a run. Live values reset to memtest_vulkan's authoritative numbers at each new report.
- Sensor poll loop made robust to internal exceptions. Previously, a failure in any part of the 1Hz telemetry poll would silently kill the reschedule, halting all sensor capture for the rest of the run — manifesting as short or empty chart phase bands in reports. The poll body is now wrapped in try/finally so the reschedule always fires, with failures logged to the stress log instead of disappearing silently.
- Phase duration diagnostic — the stress log now warns when a test phase ends more than 5% off its expected duration, so future "the report shows a short phase band" reports have a clear paper trail.
What's new in v12.1
- Idle thermal warning — new heuristic that catches CPU cooler problems by their thermal signature (low utilization but high temp). A healthy idle CPU should sit at 30–50°C; sustained 70°C+ at near-zero load means the heatsink isn't removing heat. Surfaces as a live red banner on the Stress page when the condition holds for 8+ consecutive seconds, and as a flag in the health report with detailed cause analysis (loose mounting, dried thermal paste, failing AiO pump, dead fan, dust buildup). Includes a 90s cooldown after stress runs and dismissable mute.
- VRAM panel polling fix — the previous implementation short-circuited on unchanged file size, but memtest_vulkan's stdout is full-buffered (4 KB chunks on Windows) so the file grew in bursts and the UI froze for 5–15 seconds at a time. Now re-parses every 0.25s regardless. Plus a "last update X seconds ago" indicator that explains memtest_vulkan's natural reporting cadence (which grows from every-iteration early in the run to every-10-30+ iterations later — that's by design, not a hang).
What's new in v12.0
A polish-and-correctness release on top of v11's feature additions. See the full v12 entry in CHANGELOG.md for details.
- Zoomable performance charts — drag any chart in a stress report to brush-zoom on a region; double-click or click "Reset Zoom" to restore. Useful for inspecting individual cycles in multi-cycle runs.
- Multi-cycle counting fixed — the Power test was incorrectly inflating CPU and GPU cycle counts. Power now has its own metric bucket, its own cycle list, and its own card in reports.
- Network test accuracy improvements — 8 parallel streams (matching Speedtest.net), TCP_NODELAY on upload, pre-allocated random buffers (5-10× upload speedup vs v11), and 256 KB chunks
- False packet loss fixed — the network test was counting subprocess errors during heavy load as dropped packets. Now uses a three-state ping result that distinguishes real timeouts from tool-side errors.
- Honest accuracy framing in the network test description — explains that Cloudflare's
__upendpoint has a known performance ceiling and recommends Speedtest.net or Waveform for accurate upload measurement above ~600 Mbps. The bufferbloat grade and packet-loss-under-load remain the most diagnostically useful outputs. - Python 3.11 build compatibility fix and Cloudflare bot management bypass (browser-like User-Agent + headers).
What's new in v11
- Network & Bufferbloat Test — measures download/upload speed, idle latency, packet loss, and bufferbloat (latency under load) against Cloudflare's public endpoint. Multi-stream HTTP for accurate measurement on connections above 1 Gbps. Bufferbloat grade follows the Waveform/DSLReports A+/A/B/C/D scale. Live charts with hover tooltips and Wi-Fi detection warning.
- Burn-in / multi-cycle stress testing — run each test 1-5 times in a single run with a cycle dropdown next to Duration. Live runtime estimate label updates as you toggle tests. Per-cycle metrics merging with totals summed, rates recomputed, and per-cycle history preserved on each test card.
- Per-cycle report tabs — each test card in the HTML report has tabs for Aggregate / Cycle 1 / Cycle 2 / etc. Cycles that deviate substantially from the median (>10% warn, >25% bad) get badged on their tab labels with explanatory banners.
- TDR (display-driver crash) detection — automatic Windows Event Log scan at the end of every stress run, looking for TDR events from
nvlddmkm,amdkmdap,igdkmd64, and the kernelDisplayprovider. Yellow-bordered section in the HTML report with timestamps and event details. - Fake-boost / hidden-throttling detection — cross-checks reported CPU clock vs measured throughput across cycles. Flags the fake-boost pattern (clock stays flat while throughput drops) seen on cheaper boards with undersized VRMs. Cross-references peak CPU temperature to distinguish legitimate thermal throttling from clock misreporting.
- Report comparison — side-by-side HTML diff of two stress runs (older "baseline" vs newer "comparison"). Color-coded deltas, direction-aware (lower temp is better, higher throughput is better). Useful for warranty work, before/after diagnostics, BIOS update validation. Reads from JSON sidecar files written alongside every stress report.
- Test profile save/load — save the current test selection + duration + cycles + cap settings as a named profile in the Profiles menu, recall later.
- SMART self-test auto-display — after triggering a short or long self-test, StressLab polls the drive every 30s (short) or 5min (long) and automatically displays results when the test completes.
- Report integrity stamping — SHA-256 content hash in both
.txtand.htmlreports, with a "Verify Report Integrity" utility that re-hashes and confirms the content is unchanged. Honest framing about what the check does and doesn't prove (StressLab is open source, so any HMAC key would be public). - Fan RPM range per test — each test card shows fan range during that phase ("1820 – 2400 RPM (avg 2050)" or "1500 RPM (steady)").
- Test cards aligned at bottom — "View Detailed Charts" buttons line up across all test cards regardless of how many metric rows each has.
What's new in v10
- Bundled .NET 10 sensor reader — the entire LibreHardwareMonitor stack ships pre-compiled inside StressLab.exe via PyInstaller. Customer machines need zero runtime downloads, zero compilation, zero external dependencies. No more "Rebuild Sensors" lock-while-running races.
- PawnIO replaces WinRing0 entirely — Microsoft-signed kernel driver, no Defender false positives. The PawnIO installer is bundled inside StressLab.exe and runs silently on first admin launch. Legacy WinRing0 binaries from previous installs are automatically cleaned up (including locked .sys files via reboot-deletion fallback).
- Per-test detailed metrics in stress reports — both .txt and .html exports now include CPU total ops + ops/sec, RAM passes/errors, GPU frame counts + average FPS, VRAM bandwidth (read/write GB/s) + total verified, disk SEQ1M Q8T1 speeds + total written/verified.
- Full-test HTML graph coverage — graph history expanded from 90 seconds to 30 minutes so the embedded report charts cover the entire stress run, not just the last minute.
- Direct SMART IOCTL reader — CrystalDiskInfo-style direct drive access via
IOCTL_STORAGE_QUERY_PROPERTY(NVMe) andIOCTL_ATA_PASS_THROUGH(SATA). Actual SMART attribute reads on every drive instead of "N/A" defaults. - Drive identity in health check — model, serial number, firmware revision, total host data read/written (TBR/TBW), all read directly from the drive.
- TBW endurance warnings — heuristic warning at 80% of estimated rated TBW (600 TBW per TB), error at 100%.
- SMART self-tests — short and long (extended) self-test triggers and result reading for both SATA (full support) and NVMe (read always works; trigger depends on driver).
- Windows Repair tools — SFC
/scannowand the full DISM trio (CheckHealth/ScanHealth/RestoreHealth) with live streaming output. - Service reset presets — one-click reset for Windows Update, Network Stack, Audio, Print Spooler, Windows Search, and Explorer/Shell, with cache cleanup.
For the full version history, see CHANGELOG.md. For a quick orientation to the app's tabs and buttons, see QUICKSTART.md.
Features
Stress Testing
- Sequential stress testing — run CPU → RAM → GPU → VRAM → Disk in order, or pick individual tests
- Power mode — simultaneous CPU + GPU load for PSU/thermal stress testing, with its own report card and metrics
- Burn-in / multi-cycle — repeat each selected test 1-5 times in a single run, with a live total-runtime estimate and per-cycle metric merging
- CPU stress — multi-process integer + float workload, targets 95%+ utilization across all cores
- RAM verify — multi-threaded pattern testing with VirtualLock (pinned pages), uses
memcmpfor fast in-place verification with 5 test patterns + inversions - GPU stress — adaptive OpenGL raymarching shader that auto-tunes to ~95% GPU utilization
- VRAM verify — integrates memtest_vulkan for Vulkan compute-based memory error detection (NVIDIA, AMD, Intel)
- Disk verify — unbuffered write + readback verification with per-block latency measurement, bus-type-aware speed benchmarking, configurable write cap, plus SEQ1M Q8T1 benchmark for accurate NVMe sequential speeds
- Test profile save/load — save the current selection + duration + cycles + cap settings as a named profile, recall later
Sensor Monitoring
- Live temperature monitoring — CPU, GPU, VRM, and SSD temps via the bundled .NET 10 sensor reader using LibreHardwareMonitorLib v0.9.6 over the Microsoft-signed PawnIO driver
- Live performance graphs — temperature, load%, and power graphs that update in real time during stress runs and embed in the HTML reports for the full duration of the test
- Voltage rail monitoring — +12V, +5V, +3.3V tracking with ATX12V tolerance warnings (where the motherboard SuperIO chip exposes them)
- Fan RPM range per test — each test card shows fan range during its phase
Diagnostic Detection
- Idle thermal warning — flags CPU cooler problems (loose heatsink, dried thermal paste, failing AiO pump, dead fan, dusty fins) by their thermal signature: low CPU utilization but sustained high temperature. Surfaces as a live banner on the Stress page even between test runs, and as a flag in the health report.
- TDR (display-driver crash) detection — automatic Windows Event Log scan at the end of every stress run for TDR events from
nvlddmkm,amdkmdap,igdkmd64, and the kernelDisplayprovider - Fake-boost / hidden-throttling detection — cross-checks reported CPU clock vs measured throughput across cycles. Catches cheaper boards that report inflated clocks while throttling silently.
- Network & bufferbloat test — multi-stream HTTP throughput, idle and loaded latency, packet loss, bufferbloat grade (Waveform/DSLReports A+/A/B/C/D scale)
Storage Diagnostics
- Direct SMART reader — reads NVMe SMART/Health (Log Page 0x02) and SATA SMART attributes directly via IOCTL — works where Windows'
Get-StorageReliabilityCounterreturns nothing - SMART self-tests with auto-display — trigger short/long self-tests on SATA drives, read self-test logs on NVMe drives, automatic result polling and display when the test completes
- TBW endurance tracking — warns when SSDs approach their rated total bytes written
- Speed benchmarking — auto-detects NVMe vs SATA and warns on underperformance (NVMe <1800 MB/s, SATA <400 MB/s)
- Drive identity — model, serial number, firmware revision, total host data read/written (TBR/TBW), all read directly from the drive
Reports
- Comprehensive HTML reports with embedded CSS, inline SVG charts, and dark theme — fully self-contained, no external assets
- Zoomable charts — drag any chart to brush-zoom on a region; double-click or click "Reset Zoom" to restore
- Per-cycle report tabs — multi-cycle runs get tabs for Aggregate / Cycle 1 / Cycle 2 / etc on each test card. Outlier cycles (>10% off median) get badged warnings.
- Per-test detailed metrics — CPU total ops + ops/sec, RAM passes/errors, GPU frame counts + average FPS, VRAM bandwidth (read/write GB/s) + total verified, disk SEQ1M Q8T1 speeds + total written/verified
- Peak readings dashboard — peak temps, peak power, voltage rail minimums, thermal headroom, throttle status
- Performance telemetry charts — CPU/GPU temp, load%, power, plus optional clock and fan charts; phase-banded so you can see which test was running when
- TDR events section — yellow-bordered list of any display-driver TDR events that fired during the run
- Report comparison — side-by-side HTML diff of two stress runs with color-coded deltas. Useful for warranty work, before/after diagnostics, BIOS update validation
- Report integrity — SHA-256 content hash with a Verify Report Integrity utility that re-hashes and confirms the content is unchanged
- JSON sidecar alongside every
.txtand.htmlfor the comparison feature and any future tooling - Auto-export — reports automatically saved to
Documents\StressLab Reports\on completion
Windows Tools
- Windows repair — SFC
/scannowand DISMCheckHealth/ScanHealth/RestoreHealthwith live streaming output, no PowerShell window required - Service reset presets — one-click recovery for Windows Update, Network Stack, Audio, Print Spooler, Search, Explorer/Shell
Health & System Info
- Health checks — driver status, BIOS age, TPM, Secure Boot, Windows activation, BSoD history, and direct-IOCTL SMART
- Memory configuration check — DDR generation detection, XMP/EXPO active vs rated speed, channel layout
- System info top bar — CPU + core/thread count + RAM (with DDR generation and speed) + GPU + total VRAM + Windows version
- Dark themed UI — modern dark interface built with tkinter
Requirements
For end users (running the built exe)
- OS: Windows 10 (1903+) or Windows 11 (x64)
- Privileges: Administrator (the exe self-elevates via UAC manifest)
- Network: Not required. Everything ships inside the exe.
- Runtime: None. .NET 10 is bundled, PawnIO installer is bundled, sensor reader is bundled.
For developers (building from source)
- OS: Windows 10 (1903+) or Windows 11 (x64)
- Python: 3.10 or newer
- .NET 10 SDK: required to build the sensor reader. Install from dotnet.microsoft.com.
- GPU stress: OpenGL 3.3+ capable GPU and drivers (integrated or discrete)
- VRAM test: Vulkan 1.1 capable GPU and drivers (any modern NVIDIA, AMD, or Intel GPU)
Python Dependencies
psutil>=5.9.0
wmi>=1.5.1
pywin32>=306
moderngl>=5.8.0
glcontext>=2.5.0
pyinstaller>=6.0
Install with:
pip install -r requirements.txt
Note:
modernglandglcontextare used only for the GPU stress test (OpenGL shader). They are optional — if not installed, the GPU stress test will be unavailable but everything else works.
Bundled Components
These ship inside StressLab.exe. No runtime downloads, no GitHub access, no external dependencies on customer machines.
| Component | Purpose | Size | License | Source |
|---|---|---|---|---|
| lhm_reader.exe | .NET 10 sensor reader (self-contained) | ~30 MB | MIT (StressLab) | Built locally via helper\build.bat |
| LibreHardwareMonitorLib v0.9.6 | Bundled inside lhm_reader.exe (NuGet) | included | MPL 2.0 | GitHub |
| PawnIO_setup.exe | Microsoft-signed kernel driver installer | ~3 MB | MIT | GitHub |
| memtest_vulkan.exe | VRAM error detection (Vulkan compute) | ~600 KB | zlib | GitHub |
On first launch, StressLab extracts lhm_reader.exe to %LOCALAPPDATA%\StressLab\lhm\ and runs PawnIO_setup.exe -install -silent (when running as Admin) to install the kernel driver. Both happen silently with no user interaction. Subsequent launches reuse the deployed files.
memtest_vulkan is downloaded silently in the background on startup — typically ready by the time the user clicks Start.
Usage
Run the prebuilt EXE
dist\StressLab.exe
The exe self-elevates via UAC manifest, so it always runs as Administrator. No _admin.bat wrapper needed.
Run from source
python stresslab.py
For full functionality (PawnIO install, direct SMART access, self-tests, SFC/DISM, service resets):
stresslab_admin.bat
Or right-click → Run as Administrator.
Build standalone EXE
build_exe.bat
This 5-step script:
- Installs Python dependencies via pip
- Builds the .NET 10 sensor reader (
helper\build.bat) - Stages bundled assets (copies
lhm_reader.exetoassets\, verifiesPawnIO_setup.exeis present) - Runs PyInstaller against
stresslab.spec - Verifies
dist\StressLab.exewas produced
Produces dist\StressLab.exe — a single-file executable with admin elevation built in. Final size is approximately 31 MB (UPX-compressed).
One-time setup before first build: download PawnIO_setup.exe from github.com/namazso/PawnIO.Setup/releases/latest and save it as assets\PawnIO_setup.exe. The build is otherwise fully offline-capable.
Running a test
- Select which tests to run (CPU, RAM, GPU, VRAM, Disk) using the checkboxes
- Set the duration per test (5m, 15m, or 60m)
- Optionally set the disk write cap (200GB, 500GB, or 1TB) — default 200GB
- Click ▶ START
- Tests run sequentially — progress, temperatures, and metrics update live
- When complete, a pass/fail summary is shown in the log
- Reports auto-export to
Documents\StressLab Reports\(uncheck "Auto-export" to disable) - Click Export for manual save-as to a custom location
Test Details
CPU Stress Spawns worker processes (one per logical core) running tight integer and floating-point loops. Targets 95%+ CPU utilization. Temperature is monitored throughout.
RAM Verify
Allocates ~75% of available RAM using VirtualAlloc with VirtualLock (pins pages to physical RAM, preventing swapping). Runs 5 test patterns (Solid 0x00, Solid 0xFF, Checkerboard 0xAA, Checkerboard 0x55, Random) plus their bitwise inversions across multiple worker threads. Verification uses msvcrt.memcmp for fast in-place comparison — only falls back to byte-level inspection on mismatch.
GPU Stress Renders a computationally expensive raymarching shader (SDF scene with reflections, refractions, soft shadows, ambient occlusion, and fractal noise). Adaptive algorithm adjusts shader complexity (ray steps and noise octaves) to maintain ~95% GPU utilization. Uses a background nvidia-smi poller thread for utilization feedback (no CPU impact from process spawning).
VRAM Verify Launches memtest_vulkan as a subprocess — a Vulkan compute-based memory tester that allocates as much VRAM as possible and writes/reads test patterns directly via compute shaders. Uses non-sequential memory access patterns designed to catch address bus errors that linear patterns miss. Output is read by tailing memtest_vulkan's own log file (avoids Windows pipe buffering issues). Reports iteration count, read/write bandwidth, and any bit-level errors detected. Works on any GPU with Vulkan 1.1 support.
Disk Verify
Creates a temporary test file (25% of free space, up to 2GB) and performs unbuffered write + readback verification using the Windows CreateFileW API with FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH — bypasses the entire OS filesystem cache so every write goes to NAND and every read comes from NAND.
Each pass:
- Writes 1MB blocks with a test pattern + position-dependent stamp
- Reads back each block, measures per-block latency, and verifies via
memcmp - Cycles through 5 patterns: Random (incompressible), 0xAA, 0x55, 0xFF, 0x00
Plus a SEQ1M Q8T1 benchmark phase using 8 worker threads with interleaved offsets to saturate NVMe controller queues — catches drives that pass verification but are running below their spec sequential speed.
What it catches that SMART misses:
- Bad NAND cells — write succeeds but readback data differs
- Degrading cells — blocks >10ms read latency (SSD needs internal retries)
- Controller issues — data corruption in the I/O path
- Fake/counterfeit drives — later blocks return garbage
- Speed degradation — auto-detects NVMe vs SATA via WMI and warns if speeds fall below expected thresholds
The write cap (200GB / 500GB / 1TB) limits total bytes written to protect drive endurance. A 200GB test uses ~0.03% of a typical 600 TBW SSD's lifetime. If the cap is reached before the timer expires, the test completes early automatically.
Power Mode Runs CPU stress and GPU stress simultaneously for maximum system-wide thermal and power delivery stress testing.
SMART Health Check
The SMART check on the Health tab uses direct IOCTL reads (CrystalDiskInfo-style) for accurate data on every drive — no more falling back to "N/A" defaults.
For each drive it reports:
- Identity: model, serial number, firmware revision
- Health, wear percentage, power-on hours, power cycles, temperature
- Total host data read and written (TBR / TBW)
- NVMe-specific: critical warnings, available spare percentage
- SATA-specific: pending sectors, uncorrectable sectors, reallocated sectors
Warning thresholds
| Trigger | Status | Threshold |
|---|---|---|
| Wear % over 80 | Error | NVMe Percentage Used > 80, or SATA Wearout (0xE9) value < 20 |
| Wear % over 50 | Warning | (same attributes, intermediate range) |
| Power-on hours over 35,000 | Warning | About 4 years of 24/7 operation |
| Uncorrected read errors | Error | Any non-zero count |
| NVMe media errors | Error | Any non-zero count |
| NVMe critical warning bits set | Warning | Any of bits 0–4 from the SMART log byte 0 |
| NVMe spare below threshold | Warning | Available spare % < drive's reported threshold |
| SATA pending sectors | Error | Any non-zero count |
| SATA uncorrectable sectors | Error | Any non-zero count |
| SATA reallocated sectors over 100 | Warning | Attribute 0x05 raw count |
| Drive Windows HealthStatus not "Healthy" | Error | From Get-PhysicalDisk |
| TBW over rated endurance | Error | Host writes >= estimated 600 TBW per TB capacity |
| TBW approaching rated endurance | Warning | Host writes >= 80% of estimated 600 TBW per TB |
The TBW heuristic of 600 TBW per TB is representative of mid-to-high consumer TLC SSDs (Samsung 970 EVO, WD Black SN850, Crucial MX500). QLC drives are typically rated lower (Samsung 870 QVO 1TB is 360 TBW). The warning surfaces both written total and estimated rating so you can compare against the manufacturer's actual datasheet.
SMART Self-Test (Utilities tab)
Triggers the drive's built-in self-test. The drive runs the test in its own firmware so you can keep using your computer normally.
- Short test (~2 min): electrical/mechanical health check
- Long test (1–2+ hours): reads every sector
SATA drives — full support via IOCTL_ATA_PASS_THROUGH with SMART EXECUTE OFF-LINE IMMEDIATE (cmd 0xB0 / feat 0xD4). Trigger and read both work.
NVMe drives — read always works (uses IOCTL_STORAGE_QUERY_PROPERTY with NVMe Log Page 0x06). Trigger requires the NVMe driver to expose IOCTL_STORAGE_PROTOCOL_COMMAND writes, which most consumer NVMe drivers (including Microsoft's stornvme on older Windows builds) don't do. StressLab detects this on click and shows a list of vendor utilities you can use to trigger the test, then come back to View Results to see the outcome.
Windows Repair (Utilities tab)
Live-streamed output for the standard Windows repair toolkit:
- SFC /scannow — scans and repairs system files (typically 5–15 minutes)
- DISM /CheckHealth — quick component store check (no changes)
- DISM /ScanHealth — full integrity scan (5–10 minutes, read-only)
- DISM /RestoreHealth — repair component store from Windows Update (10–30 minutes, downloads if needed)
Output streams in real-time to the panel — no detached PowerShell window. SFC's UTF-16 console output is decoded properly.
Service Reset Presets (Utilities tab)
One-click stop / cache-cleanup / start cycle for commonly broken services. Each preset shows a confirmation dialog with what it will do before running.
| Preset | What it does |
|---|---|
| Windows Update | Stops BITS, wuauserv, appidsvc, cryptsvc; renames SoftwareDistribution and catroot2 with timestamped backup; restarts services |
| Network Stack | Stops Dnscache; runs netsh winsock reset, netsh int ip reset, ipconfig /flushdns /release /renew |
| Audio | Stops/starts Windows Audio + Audio Endpoint Builder |
| Print Spooler | Stops spooler, clears %SystemRoot%\System32\spool\PRINTERS\*, starts spooler |
| Windows Search | Stops/starts WSearch (often fixes Start menu search) |
| Explorer / Shell | Kills and restarts explorer.exe (taskbar, Start menu, desktop) |
Auto-Export
When enabled (default), health check results and stress test certificates are automatically saved to:
%USERPROFILE%\Documents\StressLab Reports\
Filenames include the hostname and timestamp, e.g. StressLab_Stress_DESKTOP-ABC_20260301_143022.txt. Both .txt and .html versions are saved every time. The "Auto-export" checkbox appears on both the Health and Stress tabs. Manual export via the Export button is always available regardless of this setting.
The HTML version of the stress report includes embedded SVG performance charts covering the full test duration, a peak readings dashboard, and per-test detailed metrics (CPU ops/sec, RAM passes, GPU frame counts, VRAM bandwidth, disk MB/s).
Architecture
StressLab is a single-file Python application (~5,500 lines) plus a separate .NET 10 sensor reader (~700 lines of C# across 5 files). Both ship pre-compiled inside StressLab.exe.
Top-level layout
StressLab/
├── stresslab.py # Main application (Python)
├── stresslab.spec # PyInstaller spec - bundles helper + PawnIO into exe
├── stresslab.ico # Application icon
├── requirements.txt # Python dependencies
├── stresslab_admin.bat # Run-as-admin launcher (source mode)
├── build_exe.bat # 5-step build pipeline
├── helper/ # .NET 10 sensor reader source
│ ├── lhm_reader.csproj # Project file (NuGet ref to LibreHardwareMonitorLib 0.9.6)
│ ├── Program.cs # Entry point, poll loop, JSON output
│ ├── SensorReading.cs # Output struct + source-generated JSON context
│ ├── SensorMatcher.cs # Per-SensorType dispatch with vendor-name matching
│ ├── SensorDumper.cs # Diagnostic dump mode
│ ├── StdoutRedirector.cs # Module initializer - silences native lib chatter
│ ├── build.bat # dotnet publish wrapper
│ └── README.md # Helper-specific docs
├── assets/ # Bundled into exe via PyInstaller --add-data
│ ├── lhm_reader.exe # Built by helper/build.bat
│ └── PawnIO_setup.exe # Manual one-time download from namazso/PawnIO.Setup
├── LICENSE # MIT license
├── THIRD_PARTY_LICENSES # Bundled component licenses
├── README.md # This file
├── CHANGELOG.md # Version history
└── QUICKSTART.md # Quick orientation guide for end users
Python dependencies
- tkinter — UI framework (ships with Python)
- psutil — CPU/RAM metrics and process management
- wmi — Windows system information queries
- moderngl — OpenGL context and shader rendering for GPU stress
- ctypes — direct Windows API calls (VirtualAlloc, VirtualLock, CreateFileW, kernel32, msvcrt, IOCTL pass-through, MoveFileEx for reboot-deletion)
- subprocess — manages memtest_vulkan, lhm_reader, PawnIO installer, and SFC/DISM streaming
- multiprocessing — CPU stress worker processes
- threading — RAM verify workers, disk verify worker, nvidia-smi poller, temperature reader, async stop handlers, repair output streamers
Temperature Monitoring Priority Chain
- lhm_reader.exe (bundled) — pre-compiled .NET 10 helper using LibreHardwareMonitorLib v0.9.6 over the PawnIO driver. Best coverage; this is the primary path on every Phase 2 install.
- WMI OHM/LHM namespace — fallback if user runs LHM/OHM GUI separately
- nvidia-smi — fallback for NVIDIA GPU temperature only
- WMI thermal zone — basic CPU fallback
The helper subprocess streams JSON sensor lines on stdout at 1 Hz. Python parses each line and updates the live displays. Native library chatter (Intel Level Zero, NVIDIA driver banners) is silenced via a [ModuleInitializer] that redirects the OS-level stdout handle to NUL before any other code runs.
SMART Reading
Direct IOCTL pass-through, requires Administrator. Two paths:
- NVMe →
IOCTL_STORAGE_QUERY_PROPERTYwithStorageDeviceProtocolSpecificPropertyreading NVMe Log Pages 0x02 (SMART/Health), 0x06 (Self-test log), and CNS 0x01 (Identify Controller). Works on every NVMe driver including Microsoft's stornvme. - SATA →
IOCTL_ATA_PASS_THROUGHsending SMART READ DATA (0xB0/0xD0), SMART READ LOG (0xB0/0xD5), IDENTIFY DEVICE (0xEC), and SMART EXECUTE OFF-LINE IMMEDIATE (0xB0/0xD4) for self-tests.
Runtime data (auto-created)
%LOCALAPPDATA%\StressLab\
├── lhm\
│ └── lhm_reader.exe # Extracted from bundle on first launch (~30 MB)
└── memtest_vulkan.exe # Downloaded on first launch (~600 KB)
PawnIO driver lives at C:\Program Files\PawnIO\PawnIO.sys and is registered as a kernel-mode service named PawnIO. It's installed silently on first admin launch via the bundled PawnIO_setup.exe -install -silent.
Auto-exported reports
%USERPROFILE%\Documents\StressLab Reports\
├── StressLab_Health_HOSTNAME_YYYYMMDD_HHMMSS.txt
├── StressLab_Health_HOSTNAME_YYYYMMDD_HHMMSS.html
├── StressLab_Stress_HOSTNAME_YYYYMMDD_HHMMSS.txt
└── StressLab_Stress_HOSTNAME_YYYYMMDD_HHMMSS.html
Build
The default stresslab.spec produces a single-file --onefile exe with admin elevation and bundled assets. The full pipeline is just build_exe.bat. For better Defender behavior (occasionally an issue with single-file PyInstaller bootstraps), switch to --onedir by editing stresslab.spec:
exe = EXE(pyz, a.scripts, [], exclude_binaries=True, name='StressLab',
debug=False, strip=False, upx=True, console=False,
uac_admin=True, icon='stresslab.ico')
coll = COLLECT(exe, a.binaries, a.datas, strip=False, upx=True,
upx_exclude=[], name='StressLab')
This produces a dist\StressLab\ folder you ship as a zip. Defender heuristics flag the self-extracting --onefile mode much more aggressively than --onedir.
Troubleshooting
Temperatures show as "—" Run as Administrator so PawnIO can install. Once the driver is registered, temperatures will appear after a quick app restart. PawnIO is Microsoft-signed and won't trigger Defender.
"PawnIO needed — restart as Admin to install"
StressLab needs administrator privileges to install the PawnIO kernel driver. The exe self-elevates via UAC, so this typically only appears when running from source — use stresslab_admin.bat or right-click → Run as Administrator.
SMART check shows "100% health" or "N/A" power-on hours
You're running without admin privileges, so the direct IOCTL path is unavailable and StressLab falls back to PowerShell's Get-StorageReliabilityCounter which returns nothing on many drives. Run as Administrator for the full direct-IOCTL SMART data.
NVMe self-test "Cannot trigger" error
Your NVMe driver doesn't expose IOCTL_STORAGE_PROTOCOL_COMMAND for command writes. This is the case for most NVMe drivers including Microsoft's stornvme on older Win10/11 builds. Workaround: trigger the test from the drive vendor's utility (Samsung Magician, WD Dashboard, Crucial Storage Executive, etc.), then come back to StressLab and click "View Results" — the result reading path works on all NVMe drives.
"memtest_vulkan not found" during VRAM test The auto-download may have failed (firewall, no internet). Go to the Utilities tab and click "Download memtest_vulkan" manually. Requires internet access to GitHub.
Windows Defender flags the exe
With v10's switch to PawnIO and pre-compiled bundled helper, the WinRing0 false-positive issue is gone. If your bundled StressLab.exe is still flagged, it's likely the PyInstaller --onefile heuristic. Switch the spec to --onedir mode (see Build section). You can also submit the binary to Microsoft for whitelisting at microsoft.com/wdsi/filesubmission (www.microsoft.com).
Sensor reader not deployed / "Reinstall Sensors" button
On the Utilities tab there's a Reinstall Sensors button that re-extracts the bundled lhm_reader.exe to %LOCALAPPDATA%\StressLab\lhm\ and restarts the helper subprocess. Useful after StressLab updates (auto-detected by helper file size — anything under 1 MB at the helper path is recognized as a legacy stub and replaced automatically on launch). No reboot needed.
GPU stress test unavailable
Install moderngl and glcontext: pip install moderngl glcontext. Requires OpenGL 3.3+ drivers.
GPU utilization settles below target The adaptive algorithm needs nvidia-smi for feedback. Ensure NVIDIA drivers are installed. On AMD/Intel GPUs, the shader runs at fixed high complexity without adaptive tuning.
Disk test shows low speeds on NVMe If the test file is small relative to the drive's SLC cache, speeds may appear normal even on a degrading drive. Use the 500GB or 1TB write cap to push past the cache and measure steady-state performance. Low speeds on pass 1 are ignored (cold start).
UEFI reboot fails the first time, works the second
Fixed in v10. The reboot flow now clears stale shutdown state with shutdown /a and retries automatically before reporting failure.
Windows shows "Not Activated" in health checks Correctly reports Windows activation status. WMI license codes 0 (Unlicensed) and 5 (Notification) are both reported as "Not Activated".
SSD shows 94°C false alert (older builds) Fixed in v10. Earlier builds were reading the SSD's static "Critical Temperature" SMART threshold (a fixed value the drive reports as "this is what hot would be") as the live current temp. The matcher now skips Warning/Critical/Threshold-named sensors and only uses live temp readings.
Build fails: "lhm_reader.exe not found"
Run helper\build.bat first to produce the .NET 10 sensor reader, then re-run build_exe.bat. Or just run build_exe.bat directly — it chains the helper build automatically. Requires the .NET 10 SDK on the build machine.
Build fails: "PawnIO_setup.exe not found"
One-time setup: download PawnIO_setup.exe from github.com/namazso/PawnIO.Setup/releases/latest and save it as assets\PawnIO_setup.exe. The build is otherwise fully offline-capable.
License
StressLab is licensed under the MIT License.
Third-party components have their own licenses — see THIRD_PARTY_LICENSES for details.
Credits
StressLab — Cincy Power Computers, LLC
Built with:
- LibreHardwareMonitor (MPL 2.0) — hardware sensor access
- PawnIO (MIT) — Microsoft-signed kernel driver
- memtest_vulkan by GpuZelenograd (zlib) — Vulkan VRAM error detection
- psutil (BSD 3-Clause) — system metrics
- moderngl (MIT) — OpenGL rendering