Automatically adjust the CPU cores and RAM of Proxmox VE virtual machines based on how much of each they are actually using.
A systemd service that connects to your Proxmox nodes over SSH and drives the standard qm and pvesh tools. No agent inside the guests, no API token.
📖 Documentation — installation, configuration reference, troubleshooting, security model and known limitations.
Every check_interval seconds, for each VM you list: confirm the guest is running, check that the host still has headroom, read the guest's CPU and RAM usage, and compare it against your thresholds. Above the high mark it adds one core or 512 MB; below the low mark it removes one. Limits and a per-resource cooldown bound how far and how fast.
With hotplug and NUMA enabled on a guest, vCPU and balloon memory changes apply live. Where they cannot, the service says so in the log rather than pretending.
→ How scaling decisions are made
- No horizontal scaling — it never creates, clones, destroys or migrates a VM
- No LXC containers — see proxmox-lxc-autoscale
- No disk, network or GPU scaling — CPU cores, vCPUs and memory only
- No prediction — one instantaneous sample per cycle, no smoothing or trend analysis
- Proxmox VE 6.0 or newer on the target nodes
- Python 3.10 or newer (CI tests 3.10 – 3.12)
- SSH access to each node as a user who can run
qm set— in practiceroot paramiko,PyYAML,requests
Important
For changes to apply to a running guest, enable both:
- NUMA — VM → Hardware → Processors → Enable NUMA
- Hotplug — VM → Options → Hotplug → CPU and Memory
NUMA is a topology change and needs a guest reboot to take effect. The service can configure both for you with auto_configure_hotplug: true.
bash <(curl -s https://raw.githubusercontent.com/fabriziosalmi/proxmox-vm-autoscale/main/install.sh)This installs the latest release tag. Set VM_AUTOSCALE_REF=main to install the development branch instead.
Caution
This pipes a remote script into a root shell, unsigned and unverified. Read it first, or follow the manual install.
The service is enabled but not started, so you can configure it first:
sudo nano /usr/local/bin/vm_autoscale/config.yaml
sudo systemctl start vm_autoscale.service
journalctl -u vm_autoscale.service -fscaling_thresholds:
cpu: { high: 80, low: 20 }
ram: { high: 85, low: 25 }
scaling_limits:
min_cores: 1
max_cores: 8
min_ram_mb: 1024 # NUMA misbehaves below 1 GB
max_ram_mb: 16384
check_interval: 300
scale_cooldown: 300
proxmox_hosts:
- name: pve1
host: 10.0.0.11
ssh_user: root
ssh_key: /root/.ssh/vm_autoscale_ed25519
ssh_port: 22 # required, no default
virtual_machines:
- { vm_id: 101, proxmox_host: pve1, scaling_enabled: true, cpu_scaling: true, ram_scaling: true }
host_limits:
max_host_cpu_percent: 90
max_host_ram_percent: 90The whole file is validated at startup — types, ranges, referential integrity — and the service refuses to start on a bad one, listing every problem at once rather than the first. An unknown key is a warning, so a typo is reported instead of silently doing nothing.
Gotify and SMTP notifications, billing tracking and hotplug auto-configuration are optional. The configuration reference covers every key and what the code actually does with it.
Warning
config.yaml holds your Proxmox SSH credentials in plain text. It must be root-owned and mode 600 — the installer does this. See the hardening guide.
dry_run: trueEverything is evaluated and nothing is changed: no qm set is issued, the log records what would have happened, and notifications carry a [DRY RUN] prefix.
[dry-run] VM 101: would run `qm set 101 -vcpus 3`
An optional Prometheus endpoint, off by default and bound to localhost when on:
metrics:
enabled: true
bind: 127.0.0.1
port: 9808Exports cycle count and duration, per-VM CPU/RAM and running state, scaling actions by resource and direction, failures, and per-node utilisation. A metric that could not be read is absent rather than zero.
| Getting started | Installation, first scaling VM, how decisions are made |
| Configuration reference | Every config.yaml key |
| Troubleshooting | SSH failures, VMs that never scale, usage stuck at 0% |
| Known limitations | What is broken or missing, and the workarounds |
| Threat model | What running this as root exposes |
Bug reports, fixes and features are welcome — see CONTRIBUTING.md. For anything beyond a bug fix, open an issue first.
Security issues go through private disclosure, never a public issue.
Code contributions from Specimen67 and brianread108.
Paid support, custom development and consulting — infrastructure automation, hardening, monitoring and detection: fabrizio.salmi@gmail.com
- proxmox-lxc-autoscale — the same idea for LXC containers
- proxmox-lxc-autoscale-ml — LXC scaling driven by a model rather than thresholds
More projects at github.com/fabriziosalmi.
MIT — see LICENSE.
Caution
This software resizes live virtual machines using credentials for root on your hypervisors. The author assumes no responsibility for any damage or disruption arising from its use. Pilot it on VMs you can afford to disturb.