A small Windows GUI that caps the temperature of AMD Ryzen CPUs (desktops and laptops) by writing the SMU thermal limit through the signed PawnIO driver.
Windows 11 now blocks the old WinRing0 driver that ryzenadj and
Ryzen Controller used, and Defender actively removes WinRing0x64.sys.
Those tools fail with Unable to init ryzenadj / unable to apply ryzenadj.
This project uses PawnIO, a Microsoft-signed kernel
driver, together with ZenMaster
(the zenmaster Python package) to talk to the SMU without the blocked driver.
- Set a temperature ceiling (
Tctl, SMUTHM LIMIT CORE) in °C. - Live readout of current Tctl, load, package power and iGPU clock.
- Read-back of the limit actually stored in the SMU.
- Optional background scheduled task that keeps the limit applied: at logon, after resume from sleep and every N minutes.
- Task status line (last run, result, next run) and a repair button.
- Restore the original SMU limit (captured before the app took over; falls back to 95 °C when it was never captured) and pause the automatic re-apply.
- Update checker: asks GitHub on start, shows installed and latest versions, and can download, verify and install a new release by itself.
- Single-instance guard: a second launch brings the existing window to the front.
- Per-user settings, About dialog with licenses, diagnostics, reset and an "Open data folder" action.
- Update dialog with release notes, download progress and "skip this version".
- Notification-area icon with quick actions and an optional close-to-tray.
- Read-only thermal watchdog: warns if the SMU limit differs from the requested one or if the CPU stays above the ceiling (it never changes the limit).
- No WinRing0, no unsigned drivers, no kernel patch.
- Windows 10/11 (64-bit).
- An AMD Ryzen CPU supported by ZenMaster (Zen 1 through Zen 5).
- PawnIO installed.
- Python 3.10+ if you run from source.
-
Install the PawnIO driver (signed, by namazso): https://github.com/namazso/PawnIO.Setup/releases/latest/download/PawnIO_setup.exe
-
Install the app:
git clone https://github.com/socrabs151/ryzen-temp-limit.git cd ryzen-temp-limit py -m venv .venv .venv\Scripts\python.exe -m pip install -e .
-
Run it (it will ask for administrator rights through UAC):
.venv\Scripts\ryzen-temp-limit-gui.exeor, without installing the package:
.venv\Scripts\python.exe run.py
- Set Temperature limit and press Apply.
- Tick Keep applied in the background to install a scheduled task that re-applies the limit automatically. The task runs as the current user.
- Run now triggers the background task once.
- Pause removes the background task; the current limit stays until reboot.
- Restore applies the SMU limit that was present before the app first managed it. That value is captured once, on a start where no background task exists. If it was never captured (the app was already managing the limit), the button says so and falls back to 95 °C. To capture the firmware default, pause the task, reboot, then start the app.
- Untick the checkbox to remove the task.
- Keyboard: Tab/Shift+Tab move between controls, Enter applies, Ctrl+Q quits.
- The tray icon offers Show window, Apply limit, Restore, Pause, Check for updates and Exit. With Close window to tray enabled, closing the window hides it instead of quitting.
The temperature ceiling is volatile: the SMU forgets it on reboot, resume
and sometimes on firmware resets. That is why a background task exists at all —
any tool that changes --tctl-temp has the same limitation.
On start the app asks GitHub for the latest release. If a newer version exists, it offers to update. The bottom bar also has a Check for updates button and shows the installed and the latest known version.
Packaged builds download the new release, verify its SHA-256 checksum, replace their own files after the process exits and restart. A source checkout opens the release page instead.
Releases are produced from tags by .github/workflows/release.yml:
v0.2.0
├── RyzenTempLimit-win64.zip (onedir build, fast start)
├── RyzenTempLimit-onefile.exe (single file)
├── sha256sums.txt
└── source archives (added by GitHub)
The updater closes other running instances before replacing files. Builds before 0.3.6 cannot self-update (they left a tray process alive); install 0.3.6 manually once, later updates work normally.
The workflow refuses to publish if the tag and ryzen_temp_limit.__version__
differ. To ship a new version, bump the version, commit, then push a matching
vX.Y.Z tag.
The application is unsigned, so heuristics may complain about things that are legitimate here:
- the background job is a scheduled task that runs as the current user
(
InteractiveToken, highest privileges) at logon and callsryzen-temp-limit --apply-only. It is not a SYSTEM service; - updates are downloaded to
%LOCALAPPDATA%\RyzenTempLimit\update, verified against the published SHA-256 and applied after the app exits.
If Defender flags the unsigned build or its background task
(Behavior:Win32/Execution or Behavior:Win32/Persistence), it is a false
positive: the app registers its own scheduled task. If you trust the build, add
an exclusion for the install folder, the RyzenTempLimit.exe process and the
C:\Windows\System32\Tasks\RyzenTempLimit task file. Code signing is the
permanent fix.
Default build produces a folder (onedir), which starts in about 0.3 s:
powershell -ExecutionPolicy Bypass -File scripts\build.ps1Result: dist\RyzenTempLimit\RyzenTempLimit.exe (~28 MB folder).
A single-file build is also available. It is ~12 MB but takes 1–1.5 s to start because it unpacks itself on every launch:
powershell -ExecutionPolicy Bypass -File scripts\build.ps1 -OneFileResult: dist\RyzenTempLimit.exe.
Build artefacts are not committed — dist/ is ignored. Ship them as GitHub
Release assets. Either build still needs the PawnIO driver on the target
machine, and a manual launch still asks for administrator rights (UAC).
- Settings:
%LOCALAPPDATA%\RyzenTempLimit\settings.json - Log:
%LOCALAPPDATA%\RyzenTempLimit\app.log - Downloaded updates:
%LOCALAPPDATA%\RyzenTempLimit\update - Scheduled task:
RyzenTempLimit(current user, highest privileges)
Settings from the old %ProgramData%\RyzenTempLimit location are migrated
automatically on first start.
The application has no telemetry; see PRIVACY.md.
- Untick Keep applied in the background and close the app.
- Delete the folder
%ProgramData%\RyzenTempLimit. - Optional: uninstall PawnIO and any other hardware tools that used it.
The watchdog only reports problems. It does not lower or raise the limit by itself; a firmware that ignores the SMU command can only be detected, not fixed from user space.
- Lower temperatures mean lower sustained performance. A limit well below the firmware default will throttle aggressively under load.
- This is a software limit. It does not fix dust, a dried thermal paste or a failing fan — if a laptop shuts down from overheating, service the cooling.
- Only the thermal limit is exposed. The CLI backend (
zenmaster) supports other SMU knobs, but this GUI intentionally stays small. - The
zenmasterpackage is a third-party project and is pinned below 2.0. - Not affiliated with AMD, HP, namazso or the ZenMaster authors.
Free code signing provided by SignPath.io, certificate by SignPath Foundation.
See SIGNING.md for the build and signing details.
GNU General Public License v3.0. See LICENSE.
The project is GPL-3.0 because binary builds bundle zenmaster, which is GPL-3.0-only. Source is always available in this repository; any redistributed build must comply with the GPL (ship the license and make the corresponding source available).
Third-party components and their licenses are listed in THIRD_PARTY_NOTICES.md.
