Technical

Automatically Suspend VMs After Shutdown of Proxmox Host

Automatically Suspend VMs After Shutdown of Proxmox Host

Automatically suspend VMs after shutdown of Proxmox host is one of those things that sounds straightforward until you actually try it. The old forum threads are full of init.d scripts that don’t work on current PVE 8, and half of them just hang your shutdown anyway. Here’s what actually works.

Woman using a laptop in a server room, showcasing modern technology and work environment.

The problem with the old advice

Most of the top search results tell you to drop a script in /etc/init.d/ and symlink it into the runlevels. That’s the old SysV way, and Proxmox 8 runs systemd. It’ll ignore your init script, or worse, run it at the wrong time and leave VMs in a weird state. I’ve also seen suggestions to use qm suspend in a loop, but without proper ordering your host might power off before the suspend finishes. Annoying.

The fix: a systemd service that actually works

Instead of fighting with init.d, just write a systemd service that runs before the host goes down. It’ll iterate over all running VMs, suspend each one, and wait for them to actually suspend before proceeding. Here’s the service file:

[Unit]
Description=Suspend all running VMs before shutdown
Before=shutdown.target reboot.target halt.target
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/suspend-vms.sh
TimeoutStopSec=300

[Install]
WantedBy=multi-user.target

And the script at /usr/local/bin/suspend-vms.sh:

#!/bin/bash
# Suspend all running VMs before host shutdown

for vmid in $(qm list | awk 'NR>1 {print $1}'); do
    vmstatus=$(qm status $vmid | awk '{print $2}')
    if [ "$vmstatus" == "running" ]; then
        echo "Suspending VM $vmid..."
        qm suspend $vmid --todisk 1
        # Wait for the VM to actually suspend
        while [ "$(qm status $vmid | awk '{print $2}')" != "suspended" ]; do
            sleep 1
        done
    fi
done

Make the script executable: chmod +x /usr/local/bin/suspend-vms.sh. Then enable the service:

systemctl enable suspend-vms.service
systemctl start suspend-vms.service

Now when you reboot or shut down the host, systemd runs this service first. It suspends each VM to disk (so RAM is saved) and waits until the suspend is confirmed before moving on. The TimeoutStopSec=300 gives it five minutes to finish—plenty for a handful of VMs, but adjust if you have a ton of them.

An IT professional operates a computer in a server room, managing network systems and connected devices.

Why this beats the old methods

No more guessing about runlevels. The Before=shutdown.target line ensures this runs before anything else tries to kill processes. And using qm suspend --todisk means your VMs resume right where they left off when the host comes back up—no cold boot needed. If you’re running something like ZFS replication, this also avoids corrupting a VM that’s mid-write when the host pulls the plug.

One thing to watch: if a VM is doing something stupid and won’t suspend, the shutdown will hang until the timeout. Not ideal, but still better than a hard power-off. You could add a qm stop fallback after a shorter timeout if you’re paranoid, but I’d rather have a hung shutdown I can debug than a corrupted VM disk.

If you’d rather pay for this

If scripting isn’t your thing, Proxmox VE with a subscription gets you access to the enterprise repo and support, but it won’t do this for you out of the box. The closest paid option is a managed Proxmox hosting service—they handle shutdown ordering as part of their stack, but you’re looking at $50+/month for a single node. Honestly, just use the systemd service. It’s free and takes five minutes.

Leave a comment

Comments are reviewed before they appear. Your email is never published.