Ever had one virtual machine quietly eat every spare CPU cycle on your Proxmox host while everything else slows to a crawl? It happens more often than you'd think, especially in homelabs where three or four VMs share the same aging quad-core box. The fix isn't buying more hardware. It's telling Proxmox exactly how much CPU each guest is allowed to use.

Proxmox VE gives you two separate tools for this: cpulimit, which caps a VM or container at a hard ceiling, and cpuunits, which sets a relative priority when CPUs are under contention. They sound similar. They are not the same thing, and mixing them up is the reason a lot of people end up with a VM that either throttles when it shouldn't or hogs the host when it shouldn't.

This guide walks through both settings for VMs and LXC containers, using the actual GUI fields and command-line flags, on Proxmox VE 8.x and 9.x.

What You Will Learn

By the end of this tutorial you'll know how to set a hard CPU cap on a VM or container, how to use cpuunits to give one guest priority over another, how to check what's currently configured, and how to tell the two settings apart when something isn't behaving the way you expect.

What Is This Feature?

cpulimit is a hard ceiling on CPU time, expressed as a floating point number where 1.0 equals one fully-used CPU core. Set it to 2.5 and the guest can never use more than 250% of a core's worth of processing time, no matter how many vCPUs you've assigned it or how idle the rest of the host is.

cpuunits works completely differently. It's a relative weight the Linux scheduler uses to decide who gets CPU time first when multiple guests are competing for the same physical cores. It defaults to 100 on modern Proxmox installs using cgroup v2 (or 1024 if you're still on the older cgroup v1). A VM with cpuunits set to 200 gets roughly twice the CPU bandwidth of one left at the default 100 — but only when the host is actually under contention. If the host has spare capacity, cpuunits does nothing at all.

That last point trips people up constantly. cpuunits is not a limit. It's a tiebreaker. If your host has plenty of idle CPU, a VM with cpuunits at 2000 and a VM at 100 will both run flat out with no difference between them.

There's a third setting worth mentioning because people confuse it with the other two: cores. This just controls how many virtual CPUs the guest sees inside itself. It's not a performance cap at all — a VM with 8 cores assigned can still be capped down to a fraction of one core's worth of actual CPU time using cpulimit.

cpulimit vs cpuunits vs cores

SettingWhat it controlsType of effectDefault
coresNumber of vCPUs visible inside the guestNot a limit — just topology1
cpulimitMaximum CPU time the guest can ever useHard cap, always enforced0 (unlimited)
cpuunitsPriority relative to other guestsSoft, only matters under contention100 (cgroup v2) / 1024 (cgroup v1)

Why Would You Use It?

The most common reason is a shared homelab box running several VMs and containers on the same handful of cores. Without limits, a single misbehaving process — a runaway build job, a container stuck in a restart loop, a torrent client indexing at full tilt — can starve everything else running on the node, including Proxmox's own web interface.

Backup jobs are another good example. A vzdump backup running with high I/O and compression can spike CPU usage on the guest being backed up. If that guest also runs something latency-sensitive, like Home Assistant or a game server, capping its CPU during normal operation with cpulimit keeps things predictable.

cpuunits is more useful when you're not trying to hard-cap anything, just express priority. Say you run a production-ish service in one VM and a scratch VM you use for testing scripts in another. You don't want the test VM starved down to nothing, but if both are fighting for the same cores, the production VM should win. That's exactly what raising its cpuunits does, without permanently wasting capacity the way a hard cpulimit would during quiet periods.

Honestly, most homelab users never touch cpuunits. It only matters once you've got enough guests actually competing for CPU at the same time. cpulimit is the one people reach for first, usually after noticing one VM is hogging everything.

Prerequisites

You'll need a Proxmox VE 8.x or 9.x host with at least one existing VM or LXC container, root or a user account with VM.Config.CPU permission, and either shell access (SSH or the Proxmox web console) or the web GUI. Nothing here requires downtime — both settings apply live to a running guest.

Step-by-Step Tutorial

Step 1: Check what's currently configured

Before changing anything, see what's already set. For a VM, run this from the host shell, replacing 101 with your actual VM ID:

qm config 101

For a container, the equivalent is:

pct config 201

If cpulimit and cpuunits don't appear in the output at all, that means they're left at their defaults — unlimited for cpulimit, 100 (or 1024 on cgroup v1) for cpuunits. Proxmox only writes the line into the config file once you explicitly set a non-default value.

Step 2: Set a hard CPU cap on a VM

To cap VM 101 at the equivalent of two full cores, run:

qm set 101 --cpulimit 2

This takes effect immediately on a running VM — no reboot needed. To remove the cap and go back to unlimited, set it to 0:

qm set 101 --cpulimit 0

From the GUI, select the VM, go to Hardware, double-click Processors, and tick the Advanced checkbox in the dialog that opens. That reveals the CPU limit and CPU units fields alongside Sockets and Cores.

One thing to watch: cpulimit is a ceiling on total CPU time across all of that VM's vCPU threads combined, not per-core. A VM with 4 cores and cpulimit set to 2 can still peg two of those cores at 100% while the other two sit idle, or spread that same 200% evenly across all four — the scheduler decides, you're just capping the total.

Step 3: Set a priority weight with cpuunits

To give VM 101 double the default priority under contention:

qm set 101 --cpuunits 200

There's no fixed maximum, but there's also no point going wild with huge numbers unless you're comparing it against other guests you've also adjusted. What matters is the ratio between guests, not the absolute value.

Step 4: Apply the same settings to an LXC container

Containers use the same two settings, plus the cores option actually restricts visible CPUs using the Linux cpuset cgroup rather than just being cosmetic. To assign a container 2 visible cores but cap it at half a core's worth of actual CPU time:

pct set 201 --cores 2 --cpulimit 0.5

That combination is intentional in the Proxmox docs as an example — you can absolutely give a container more visible cores than its actual CPU budget allows. It's useful for software that checks core count to decide how many worker threads to spawn, without actually letting it consume that much CPU.

Setting cpuunits on a container works identically to VMs:

pct set 201 --cpuunits 2000

Step 5: Verify the change is actually working

Numbers in a config file are easy to set and easy to get wrong. Confirm the limit is real by loading the guest with something CPU-heavy and watching it from the host:

htop

Look at the qemu-kvm or pct process for that guest. With cpulimit set to 2, you should see it plateau around 200% total CPU in htop's per-process view, even while the guest itself reports 100% usage internally across all its assigned cores. If it's climbing past your configured limit, double check you actually set the value on the right VMID.

Commands Explained

CommandWhat it does
qm config <vmid>Shows the current configuration of a VM, including any CPU limits set
qm set <vmid> --cpulimit <n>Sets a hard CPU time cap on a VM, live, no reboot required
qm set <vmid> --cpuunits <n>Sets the VM's scheduling priority relative to other guests
pct config <ctid>Shows the current configuration of an LXC container
pct set <ctid> --cores <n> --cpulimit <n>Sets visible core count and a hard CPU cap on a container in one command
htopInteractive process viewer, useful on the host for watching per-process CPU time and confirming a limit is actually being enforced

Common Errors

Running qm set 101 --cpulimit abc with a non-numeric value fails with something like value 'abc' does not look like a valid float. cpulimit and cpuunits both expect numbers — cpulimit accepts decimals (0.5, 2.5), cpuunits does not, it wants a whole number.

A more subtle mistake: setting cpulimit lower than the guest actually needs for normal operation, then wondering why it feels sluggish under any real load. If you cap a 4-core VM at cpulimit 1, you've effectively given it a quarter of one core's throughput no matter how many cores it thinks it has. That's fine for a lightweight DNS server. It's a bad idea for anything running a database or doing video transcoding.

People also occasionally set cpuunits expecting it to behave like cpulimit — capping usage even when the host is idle. It won't. If nothing else on the host wants CPU, a guest with cpuunits at the default 100 will still happily use 100% of a core if it needs to. cpuunits only kicks in once there's actual competition.

Troubleshooting

If a cpulimit change doesn't seem to be taking effect, first confirm it actually saved with qm config <vmid> or pct config <ctid>. A typo in the VMID is the single most common reason a setting appears to do nothing — you changed the config of a different guest than the one you were testing.

If the limit is set correctly but the guest still seems to exceed it, check whether you're measuring from inside the guest or from the host. Guest operating systems report CPU usage relative to the vCPUs they've been told they have, not the actual host CPU time they're allotted. A guest with 4 cores and cpulimit 1 can still show "100% CPU" inside its own task manager while only actually consuming 100% of a single physical core on the host. Always verify from the host side with htop or top.

On older cgroup v1 hosts, cpuunits values behave on a different scale (1024 default instead of 100). If you're comparing ratios across a mixed environment, or you migrated a VM from an older node, check cat /sys/fs/cgroup/cgroup.controllers to see which cgroup version the host is actually running before assuming your numbers translate directly.

Best Practices

Reach for cpuunits first if all you want is fair-ish sharing between guests on a busy host. It costs you nothing when the host is idle, unlike a hard cpulimit which always caps you even at 3am when nothing else is running.

Use cpulimit specifically when you need a guarantee, not just a preference — a shared box where a noisy neighbor VM genuinely cannot be allowed to affect a specific other workload, or a backup/testing VM you deliberately want throttled regardless of what else is happening.

Don't set cpulimit equal to your host's total core count "just to be safe." It doesn't protect anything at that point since the guest could never physically exceed the host's total capacity anyway, and it just adds a config line you'll forget the reason for six months from now.

If you're managing several guests with cpuunits, write down your ratios somewhere. "VM 100 = 100, VM 200 = 300" only makes sense as a system if you remember what the numbers mean relative to each other.

Frequently Asked Questions

Do I need to reboot the VM after changing cpulimit or cpuunits?

No. Both settings apply live through the cgroup controlling the guest's process. You'll see the effect immediately, even on a VM that's been running for weeks.

What's a reasonable cpulimit for a typical homelab VM?

There's no universal number — it depends entirely on what the VM does and how many cores you gave it. A good starting point is leaving it unset (unlimited) until you actually observe a problem, then capping just the specific guest that's causing it.

Can I set cpulimit higher than the number of cores assigned to the VM?

You can, but it won't do anything useful. A VM can never use more CPU time than its assigned core count allows, so a cpulimit above that number is effectively the same as leaving it unlimited.

Does cpuunits work between a VM and an LXC container on the same host?

Yes. Both use the same underlying cgroup mechanism, so a VM's cpuunits and a container's cpuunits are compared on the same scale when they're competing for the same physical cores.

Will this affect my VM's disk performance?

No. cpulimit and cpuunits only affect CPU scheduling. If you're also seeing disk contention, that's a separate setting — Proxmox handles disk I/O limits independently through the VM's storage configuration.

Conclusion

cpulimit and cpuunits solve two different problems that happen to live in the same dialog box. One draws a hard line a guest can never cross. The other just decides who wins when guests are actually fighting over the same cores. Once you've set either on a running VM or container, there's nothing else to configure — it takes effect instantly and stays that way until you change it again.

Start with cpuunits if you just want fairer sharing on a busy node, and only reach for a hard cpulimit once you've identified a specific guest that actually needs to be capped.