Introduction

Open the Proxmox VE web interface for the first time and everything you need seems to be right there: buttons for starting a VM, a console tab, a little wrench icon for options. So why would anyone bother typing commands into a terminal instead?

Because the GUI eventually gets in your way. Maybe your browser tab crashed mid-migration and you want to check if the job actually finished. Maybe you're SSH'd into the host anyway to fix something else and clicking through six menus feels slower than typing one line. Maybe you're writing a script to spin up ten test VMs and there's no "click this 10 times" button.

That's where qm, pct, and pvesh come in. These three command-line tools are how Proxmox VE itself does almost everything the web interface does — the GUI is really just a nice wrapper around the same commands you're about to learn. Once you know them, you'll start VMs faster, debug stuck tasks without guessing, and understand what the GUI is actually doing behind the scenes.

This guide assumes you've never opened a terminal on a Proxmox host before. We'll go slow, explain what each command is for before showing it, and point out the mistakes that trip up almost everyone the first time.

What You Will Learn

  • What qm, pct, and pvesh actually are and how they relate to each other
  • How to list, start, stop, and check the status of VMs and containers from the terminal
  • How to view and change configuration settings without opening the GUI
  • How to take snapshots, clone guests, and enter a container's shell directly
  • How to query the Proxmox API straight from the command line with pvesh
  • The errors you'll almost certainly hit as a beginner, and what they actually mean
  • When you should reach for the CLI and when you're better off just using the GUI

What Is This Feature?

qm, pct, and pvesh are three separate command-line tools that ship with every Proxmox VE install. You don't install them — they're already on your host the moment you finish setup.

qm stands for "QEMU Manager." It controls virtual machines — the guests that run their own full operating system with a virtual BIOS, virtual disk, and virtual network card, the same way a VM in VMware or VirtualBox would.

pct stands for "Proxmox Container Toolkit." It controls LXC containers instead of VMs. An LXC container is a lighter-weight way to run Linux: it shares the host's kernel instead of booting its own, which makes it start in a second or two and use a fraction of the RAM a VM would. You'd reach for a container to run something like Pi-hole or Nginx Proxy Manager, and a VM for anything that needs its own kernel — Windows, a different Linux distro version, or software that pokes at low-level hardware.

pvesh is different from the other two. Instead of managing one specific type of guest, it talks directly to the Proxmox API — the same internal interface the web GUI uses for literally every button you click. If qm and pct are specialized tools, pvesh is the master key that can reach almost anything in Proxmox, including things that don't have a dedicated command yet.

All three only work when run on the Proxmox host itself (or another node in the same cluster) — they don't exist inside your VMs or containers, and there's no separate download for them.

Why Would You Use It?

Honestly, if you only ever manage two or three VMs and you're happy clicking around the GUI, you don't strictly need any of this. Nobody's going to force you into the terminal.

But there are a handful of situations where the CLI genuinely saves you time or tells you something the GUI won't:

  • Speed. Typing qm start 105 while you're already in an SSH session is faster than switching windows, finding the VM, and clicking Start.
  • Scripting. If you ever want to spin up several VMs the same way, back up a specific list of guests, or automate anything, you need commands — a mouse doesn't script well.
  • Diagnosing stuck tasks. When the GUI shows a job frozen at 99% with no useful message, running the equivalent command directly often shows you the real error instead of a spinning icon.
  • Working over a slow or console-only connection. If you're on an IPMI console or a laggy VPN, a full web interface can be painful. Plain text over SSH usually isn't.

I'd add one more honest reason: once you've used qm status and pct list a few times, they become muscle memory faster than navigating the GUI tree. It's a small thing, but it adds up.

Prerequisites

Before you start, make sure you have:

  • A working Proxmox VE install — this guide was tested on Proxmox VE 9.2, but the commands here have worked the same way since at least version 7.x
  • SSH access to your Proxmox host, or access to the Shell tab under your node in the web GUI (Datacenter → your node name → Shell)
  • At least one VM and one LXC container already created, so you have something to practice on
  • Root access, or a user account with sufficient privileges — most of these commands need to run as root, and pvesh specifically requires it

If you haven't created a VM or container yet, do that first. This guide is about managing guests that already exist, not creating them from scratch.

Step-by-Step Tutorial

Log into your Proxmox host over SSH, or open the Shell tab in the web GUI. Everything below runs from that shell.

1. List what you have

Start by seeing what's actually on the node:

qm list
pct list

qm list shows every VM on this node, its VMID, name, current status, memory allocation, and disk size. pct list does the same for containers. VMIDs matter a lot here — every command after this uses the ID number, not the name, so make a note of which number belongs to which guest.

2. Check the status of a specific guest

qm status 100
pct status 101

This tells you if VMID 100 is running, stopped, or paused. It's a quick sanity check before you try to start or stop something — running qm start on a VM that's already running just wastes a step.

3. Start, stop, and shut down

qm start 100
qm shutdown 100
qm stop 100
qm reboot 100

start boots the VM. shutdown sends an ACPI signal asking the guest OS to power off cleanly — the same as pressing a physical power button, so the guest gets a chance to close files properly. stop is the rougher option: it kills the VM immediately, like yanking the power cord. Use shutdown whenever you can, and save stop for when a guest is frozen and won't respond.

Containers use the identical pattern:

pct start 101
pct shutdown 101
pct stop 101
pct reboot 101

4. View and change configuration

qm config 100
pct config 101

This prints the guest's current settings — memory, CPU cores, disks, network devices, all of it — in the same format Proxmox stores it in on disk. To change something, use set:

qm set 100 --memory 4096
pct set 101 --memory 512

This bumps VM 100 to 4096 MB of RAM and container 101 to 512 MB. Some changes apply immediately; others (like adding a new virtual disk) need a restart to take effect, and Proxmox will tell you which is which when you run pending:

qm pending 100

5. Take a snapshot before you break something

qm snapshot 100 before-upgrade
qm listsnapshot 100
qm rollback 100 before-upgrade

A snapshot freezes the VM's disk state at that exact moment so you can roll back to it later. This is genuinely one of the most useful habits you can build — take a snapshot named something you'll recognize (like before-upgrade, not snap1) right before any risky change, like a distro upgrade inside the guest.

6. Get into a container directly

pct enter 101

This drops you straight into a root shell inside the container — no SSH needed. It's the fastest way to poke around a container for a quick check. For anything you'll want to repeat or script, though, exec is often cleaner:

pct exec 101 -- apt update

This runs apt update inside container 101 without you ever actually entering it — useful for quick one-off commands from a script.

7. Clone a VM

qm clone 9000 201 --name test-clone --full

This clones template VM 9000 into a new VM with ID 201, named test-clone. The --full flag makes a completely independent copy of the disk. Leave it off and you get a linked clone instead, which shares the original disk and only stores the differences — much faster to create, but it depends on the original VM staying intact.

8. Talk to the API directly with pvesh

pvesh get /nodes
pvesh get /nodes/pve/qemu
pvesh get /cluster/resources --output-format json

The first command lists every node in your cluster (or just yours, if you're running standalone). The second lists every VM on node pve — replace that with your actual node name. The third dumps a full JSON summary of every resource in the cluster: nodes, VMs, containers, storage, all in one machine-readable blob. That last one is particularly handy if you're feeding data into a script or a monitoring tool.

Commands Explained

CommandManagesTypical Use
qmQEMU/KVM virtual machinesStart, stop, configure, snapshot, and clone full VMs
pctLXC containersSame lifecycle actions as qm, plus entering the container shell directly
pveshThe entire Proxmox APIReading or changing anything the GUI can touch, including things without a dedicated command

A pattern worth noticing: qm and pct mirror each other almost command-for-command. Once qm start, qm stop, and qm config feel natural, pct barely needs a separate explanation — swap the VMID for a container ID and you're done. That symmetry is deliberate on Proxmox's part, and it makes learning the second tool much faster than the first.

One flag worth knowing across both tools is --help. Run qm help start or pct help set and you'll get the full list of accepted options for that specific subcommand, straight from the tool itself — faster than searching online when you just need to remember one flag name.

Common Errors

A few messages come up constantly for people new to these tools:

VM 100 is running - unable to start

You tried to start a VM that's already running. Check with qm status 100 first next time.

Configuration file 'nodes/pve/qemu-server/105.conf' does not exist

There's no VM with that ID on this node. Either you typed the wrong VMID, or that VM lives on a different node in your cluster — run qm list to double-check, or pvesh get /cluster/resources to see every guest across the whole cluster.

can't lock file '/var/lock/qemu-server/lock-100.conf' - got timeout

Another task is already running against this VM — a backup, a migration, something. Wait for it to finish. If nothing is actually running and the lock is stuck (this happens after a crashed task), see the troubleshooting section below.

500 unable to get PVE manager status

This one usually shows up with pvesh if the pvedaemon or pvestatd service isn't running properly, or if you're not running the command as root. Try re-running as root first.

permission denied

Either you're not root, or you're trying to pct enter an unprivileged container in a way your user account isn't allowed to. SSH in as root, or use sudo, and try again.

Troubleshooting

If a VM or container refuses to start and the error mentions a lock file, the guest probably has a stale lock left over from an interrupted task — a backup that got killed, a browser that closed mid-migration. First, confirm nothing is actually still running by checking qm status 100 and the Task History in the GUI. If it's genuinely stuck, clear the lock with:

qm unlock 100

For containers, the equivalent is:

pct unlock 101

Only do this once you're sure the original task actually finished or died — unlocking a VM mid-backup can corrupt things.

If pvesh commands fail with connection or authentication errors, check that you're running them as root and that the local pveproxy service is up (systemctl status pveproxy). A node that was just rebooted sometimes needs a minute before all its services are fully ready.

If a container won't pct enter at all and just hangs, it might not actually be running — pct enter silently waits rather than failing loudly in some versions. Check pct status first, and start the container if it's stopped.

Best Practices

Don't try to memorize every flag on day one. Learn list, status, start, stop, and config for both qm and pct first — that combination covers most day-to-day work, and everything else you can look up with --help when you actually need it.

Get comfortable with VMIDs early. The GUI shows you friendly names, but the CLI only cares about numbers, and mixing up 100 and 101 while running qm stop is an easy way to shut down the wrong machine.

Treat pct enter as a quick-check tool, not your daily driver for managing a container's actual services. If you're installing packages or editing config files regularly, SSH into the container directly like you would any other Linux box — it keeps your shell history and habits consistent with how you'd manage a real server.

If you find yourself running the same three or four qm/pct commands over and over to provision similar VMs, that's usually a sign it's time to look at a proper automation tool instead of a personal shell script — Proxmox works well with both Ansible and Terraform once you're past the "just learning the CLI" stage.

Snapshot before anything risky. It costs you one command and a few seconds, and it turns "I broke it, now what" into "roll back and try again."

Frequently Asked Questions

Do I need to know the CLI to use Proxmox VE?
No. The web GUI can do almost everything covered here. The CLI just gets faster once you're comfortable with it, and it's essential if you ever want to script anything.

Can I run these commands from inside a VM or container?
No. qm and pct only exist on the Proxmox host itself, since they manage guests from the outside.

What's the difference between qm/pct and pvesh?
qm and pct are dedicated tools for one job each. pvesh reaches the whole API, including parts that don't have a dedicated command — useful when you need something specific like /cluster/resources.

Is it safe to experiment with these commands on a production VM?
Take a snapshot first with qm snapshot, and you're covered for almost anything short of deleting the disk outright.

Why does qm list show a VM that pct list doesn't, or vice versa?
They only show their own guest type. A VM will never appear in pct list, and a container will never appear in qm list — check the other command if you don't see what you expect.

Conclusion

None of this replaces the web GUI, and it isn't supposed to. What it does is give you a second way in — one that's faster once it's familiar, works over a bare SSH session, and shows you plain error text instead of a spinner that never finishes. Start with qm list, pct list, and status on whatever you already have running, and let the rest come naturally as you need it. A few weeks from now, typing qm shutdown 100 will feel more natural than reaching for the mouse.