vllm-thermald
Keeps a vLLM Docker container from overheating an NVIDIA
DGX Spark, and lets AI agents read the temperature of the hardware they run on. It has no dependencies
beyond Python 3.9+, Docker and nvidia-smi.
This reduces the risk of an overheating shutdown but can't guarantee against one. It won't help if a shutdown is caused by power rather than heat, and temperatures can rise quickly between readings. It's tested on one DGX Spark, so check the limits against your own readings.
Quick start
With your vLLM container already created, on the Spark:
uv tool install vllm-thermald # or: pipx install vllm-thermald
vllm-thermald install
That checks the machine, finds your running vLLM container, and starts a service that also runs at boot.
From then on, the daemon starts vLLM whenever it's stopped and cool. To stop vLLM on purpose, run
vllm-thermald hold first.
How it works
It checks temperatures every second and acts when a sensor crosses a limit:
| Situation | GPU | Board | Action |
|---|---|---|---|
| Hot (either sensor) | 85°C | 92°C | docker pause |
| Cooled (both sensors, after at least 30s) | 70°C | 75°C | docker unpause |
| Critical (either sensor), or not cool after 10 minutes paused | 90°C | 96°C | docker kill |
| Stopped and cold (both sensors) | 60°C | 65°C | docker start |
Why it pauses first: a pause removes GPU load within seconds, keeps the model loaded, and in-flight requests continue afterwards. A restart reloads the model and runs autotune, the hottest phase, so simply turning vLLM off and on could cause the crash it's trying to avoid.
It fails safe:
- A missing sensor never counts as cool. If one is missing for 30 seconds vLLM is paused, and if both are missing it's killed.
- After a kill or failed run, restarts wait 5 minutes, doubling up to an hour. This survives daemon restarts and reboots, but a sudden power loss doesn't start a wait.
- An invalid config logs an error and uses the default limits, rather than leaving vLLM unprotected.
- systemd restarts the daemon if it crashes or hangs.
Commands
| Command | What it does |
|---|---|
vllm-thermald install [--container NAME] |
Set up and start the service |
vllm-thermald uninstall |
Stop and remove the service, keeping config and history |
vllm-thermald doctor |
Check this machine has what the daemon needs |
vllm-thermald status |
Show temperatures and actions |
vllm-thermald hold / release |
Stop vLLM being started or unpaused, or undo that. Heat protection stays active |
vllm-thermald check-config |
Validate the config file |
Logs: journalctl --user -u vllm-thermald -f
Configure
Edit ~/.config/vllm-thermald/config.json, setting only what you want to change, then run
systemctl --user restart vllm-thermald. Limits must satisfy start ≤ resume < pause < kill, and every
option is listed in Config in daemon.py.
{"container": "my-vllm", "pause_gpu": 83, "resume_gpu": 68}
History is in ~/.local/state/vllm-thermald/: thermal.csv holds readings, synced to disk so they survive
a sudden power loss, and events.jsonl holds every action with its reason.
MCP server for agents
vllm-thermald mcp is a stdio MCP server. It only reads the daemon's
files, so a fault in it can't affect protection.
| Tool | Returns |
|---|---|
thermal_status |
Temperatures, power, state, whether protection is working, headroom, trend |
thermal_policy |
Active limits, state machine, and what each state means for the agent |
thermal_history |
Temperature and power over time, slowdown counts, logging gaps |
thermal_events |
Log of daemon actions |
vllm_status |
Serve settings, model, requests, cache use, throughput |
Add it to any MCP client with the command vllm-thermald and the argument mcp. For example, with
Hermes Agent:
hermes mcp add thermald --command vllm-thermald --args mcp
While vLLM is paused, an agent running on it is frozen and can't call anything. It sees a pause only as a
gap in time, so it should check thermal_events after an unexplained delay.
To give the agent notes about your machine, put a JSON object in
~/.config/vllm-thermald/observations.json. thermal_policy returns it, so write only what the agent
should read.
Security
- No agent control: all MCP tools are read-only, so an agent can't change limits or disable its own protection.
- Local only: the MCP server uses stdio with no network port, and
vllm_urlmust be a loopback address. - Secrets: tools read the container's command but never its environment. Flags and values that look like credentials are left out on a best-effort basis, so avoid passing secrets as command-line flags.
- Docker access: the daemon needs Docker, which is effectively root on the host. Anyone who can edit its config or files can control this container.
Please report vulnerabilities privately through GitHub security advisories.
Develop
PYTHONPATH=src python3 -m unittest discover -s tests
License
Apache 2.0. An independent project, not affiliated with or endorsed by NVIDIA, the vLLM project, or Nous Research. All trademarks belong to their owners.
Metadata
Release files for vllm-thermald 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| vllm_thermald-0.1.0.tar.gz | 36.1 kB | With provenance | Details for vllm_thermald-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| vllm_thermald-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for vllm_thermald-0.1.0-py3-none-any.whl |
Total release size: 63.9 kB
Release files / vllm_thermald-0.1.0.tar.gz
| Download URL | vllm_thermald-0.1.0.tar.gz |
|---|---|
| Size | 36.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
02ed5c83ecd82e4a693435caacb3e3ea1af932446fb9d27310980af532b4af28
|
|
BLAKE2b-256 checksum How to use checksums |
85739ef9f0ae7bd6ca23dcf1d0954a600a556fc769d9a68ab53121e51a81215d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logRelease files / vllm_thermald-0.1.0-py3-none-any.whl
| Download URL | vllm_thermald-0.1.0-py3-none-any.whl |
|---|---|
| Size | 27.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef4f198b269aed1b74ac9c0526b66db7dad81f9f0eed1bdf441b4fe8483f8cc0
|
|
BLAKE2b-256 checksum How to use checksums |
5fdeb28b6d7fe091a3a5df42295711c42f5b54ecd4c5f63c3d8e67bf7bf71a43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logSecurity for vllm-thermald 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for vllm_thermald-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.