What Memory Ballooning Actually Does

Every VM you create in Proxmox VE gets a memory allocation, and by default that allocation isn't a hard, fixed number the way it looks in the Hardware tab. Unless you explicitly turn it off, Proxmox enables a feature called memory ballooning on every new VM, which lets the hypervisor and the guest cooperate to shrink or grow that VM's RAM usage while it's running, without a reboot.

This matters more than most people realize when they first set up a node. If you've ever wondered why a host with 32 GB of RAM will happily let you create VMs that add up to 48 GB of configured memory, or why a freshly booted Debian VM shows 2 GB used in free -h even though you gave it 8 GB, ballooning is almost always the reason. It's also frequently the source of confusing "why is my VM's memory usage capped" or "why won't Proxmox let me start this VM" problems once a node's actual free RAM runs low.

This article explains exactly how the balloon device works under the hood, how to configure it through the GUI and the CLI, how to test it live, and — just as importantly — when you should turn it off entirely. It assumes a working Proxmox VE 8.x or 9.x installation with at least one VM already created.

The Mechanism: How a Balloon Device Actually Frees Memory

Ballooning relies on a paravirtualized device called virtio-balloon, exposed to the guest as a small PCI device. A driver inside the guest OS talks to this device and cooperates with QEMU (the process backing your VM on the host) to move memory back and forth between "owned by the guest" and "owned by the host."

The sequence looks like this:

  1. The Proxmox host decides it wants some RAM back from a VM — usually because host memory is under pressure, or because you're using auto-ballooning with shares and another VM needs more.
  2. QEMU sends an "inflate" request to the balloon driver inside the guest, along with a target amount of memory to give up.
  3. The guest OS's own memory manager decides which pages to give up — typically page cache, buffers, and other reclaimable memory first, just like it would under normal memory pressure. It "inflates" the balloon by pinning those pages and handing them to the driver.
  4. The guest tells QEMU those physical page addresses are now free. QEMU unmaps them from the VM's address space and the host reclaims the underlying RAM to use elsewhere.
  5. When the VM needs memory back, QEMU sends a "deflate" request, the balloon driver releases the pinned pages back to the guest kernel, and the guest can allocate from them again.

The critical detail here — and the one that trips people up — is that the guest decides what to give up, not the host. The host can only ask for a target; it cannot reach in and reclaim specific pages the way it can with a container. That's also why ballooning cannot make memory disappear that the guest is actively using: if you ask a VM running a full working set in RAM to give up 4 GB it doesn't have spare, the guest will start swapping, or in the worst case its OOM killer will start terminating processes to comply.

Driver Requirements

Ballooning only works if the guest OS has a working virtio_balloon driver loaded and Proxmox's own memory management daemon (pvestatd polling the guest, combined with the QEMU monitor) can talk to it.

Guest OSRequirement
Modern Linux (kernel 3.x+)Driver is built into the kernel. Works out of the box with no extra installation as long as the VM's Hardware > Memory has a virtio balloon device attached (default for VMs created through the GUI).
Windows Server 2012/8.1 and newerInstall the VirtIO Balloon driver from the virtio-win ISO, then run the bundled balloon service installer (blnsvr.exe -i) so the service starts automatically. Without the service running, the driver is present but inert.
Older Windows versionsDriver must be installed manually via devcon, and the balloon service still needs to be registered separately.

If the driver or service isn't present, the VM simply won't respond to inflate/deflate requests — Proxmox will show the balloon as unavailable or stuck, and the VM will effectively behave as if ballooning were disabled, silently. This is one of the most common causes of "ballooning isn't working" reports, especially on Windows VMs where the driver was installed but the service was never started.

Configuring Ballooning Through the GUI

Every setting here lives in one place: select your VM, go to the Hardware tab, and double-click Memory.

  1. Memory (MiB) — this is the maximum amount of RAM the VM can ever use. With ballooning enabled, this is the ceiling, not a guarantee.
  2. Ballooning Device — a checkbox. It's checked by default on VMs created through the GUI. Unchecking it removes the virtio-balloon device from the VM entirely and pins the VM to the fixed Memory value.
  3. Minimum memory (MiB) — appears once the Ballooning Device checkbox is enabled. This is the floor: the smallest amount of RAM the host is allowed to squeeze the VM down to. Setting this equal to the Memory value effectively disables dynamic behavior even with the device still attached, since there's no range to shrink into.
  4. Shares — also appears with ballooning enabled. This is a relative weight (0–50000, default 1000) used only when the host needs to decide how to distribute spare or scarce RAM across multiple ballooning VMs at once. A VM with shares of 2000 will be prioritized for roughly double the spare memory of one left at the default 1000, proportionally. Setting shares to 0 disables auto-ballooning for that specific VM even if the device is attached, so it stays pinned near its configured target.

A sensible starting configuration for a general-purpose Linux VM you want to allow the host to reclaim from during idle periods looks like: Memory = 8192, Minimum memory = 2048, Shares = 1000. That tells Proxmox "give this VM up to 8 GB when it's busy, but you're allowed to take it down to 2 GB when the host needs the RAM elsewhere."

Configuring Ballooning From the CLI

Everything in the GUI dialog maps directly to three qm.conf keys, which you can set with qm set without touching the file directly:

# Set max memory to 8192 MiB, balloon target (min) to 2048 MiB, shares to 1500
qm set 101 --memory 8192 --balloon 2048 --shares 1500

# Disable ballooning entirely — pins the VM to a fixed 8192 MiB
qm set 101 --memory 8192 --balloon 0

# Re-enable it, letting the host reclaim down to 4096 MiB
qm set 101 --memory 8192 --balloon 4096

Reference for the underlying config keys, straight from qm.conf:

  • memory: <integer> (16 - N) — maximum RAM in MiB available to the VM. This is the ceiling when ballooning is active.
  • balloon: <integer> (0 - N) — target/minimum RAM in MiB. The balloon driver is enabled by default unless this is explicitly set to 0, which removes dynamic behavior.
  • shares: <integer> (0 - 50000), default 1000 — relative weight for auto-ballooning across VMs. 0 disables auto-ballooning for that VM.

You can inspect the current values for a running VM at any time:

qm config 101 | grep -E '^(memory|balloon|shares):'

Changes to these three values take effect immediately on a running VM — there's no need to stop and start it, which is one of the actual practical benefits of the feature: you can shrink or grow a VM's ceiling live in response to a changing workload.

Watching Ballooning Happen Live

You don't have to take Proxmox's word for it — you can trigger and observe an inflate/deflate cycle manually, which is also the fastest way to confirm the driver is actually responding on a given guest.

Open the VM's Monitor tab (or connect with qm monitor <vmid> from the shell) and issue:

balloon 4096

This asks the guest to shrink to a 4096 MiB target. Then check the actual reported size:

info balloon

You should see balloon: actual=4096 (or something converging toward it) within a few seconds if the driver is responsive. If actual never moves off the VM's full configured memory no matter what target you send, the guest driver either isn't loaded or the balloon service isn't running — go back and check the driver/service status inside the guest before assuming Proxmox is misbehaving.

From inside a Linux guest, you can watch the reclaim happen in something like watch free -h while you send the balloon command from the host — you'll see "available" and "free" shrink as pages get pinned and handed over, and cache/buffers get dropped first before anything more aggressive happens.

Why the Host Won't Always Honor Your "Memory" Setting

A common point of confusion: you set a VM's Memory field to 8192 MiB, but free -h inside the guest never seems to reach that number, or the VM's Summary graph in the Proxmox GUI shows usage well below the configured maximum even under load.

This is expected behavior when ballooning is enabled and the host isn't under pressure to give the VM more. The guest only gets granted RAM up toward the Memory ceiling as it actually asks for it (via normal allocation, which triggers deflate requests), and the host only proactively takes RAM away via inflate requests when there's contention. A VM sitting idle at its balloon (minimum) target with headroom up to Memory isn't a bug — it's the feature working as designed. If you want a VM to always show its full configured RAM regardless of host pressure, that's exactly the case where you should disable ballooning rather than fight the graphs.

Ballooning and KSM: Two Different Features That Work Together

It's easy to conflate ballooning with KSM (Kernel Samepage Merging), Proxmox's other RAM-saving mechanism, but they solve different problems and operate independently:

  • Ballooning changes how much memory a guest is allowed to hold, by actually returning pages to the host.
  • KSM runs on the host and scans physical RAM for identical pages across different VMs (extremely common when you're running several VMs of the same guest OS), merging duplicates into a single copy-on-write page. It doesn't change what any individual VM thinks it has — it just deduplicates the underlying physical backing.

The two stack cleanly: ballooning reduces the total pages a host has to manage in the first place, and KSM reduces the physical footprint of whatever pages remain resident across VMs of similar guest OSes. Neither one needs the other enabled to function, and running mixed configurations (some VMs with ballooning off for predictability, KSM still scanning across everything) is completely normal in production.

When Ballooning Helps

  • Homelabs and test/dev clusters where you routinely overcommit — running more configured VM memory than physical RAM — because most VMs are idle most of the time and you'd rather let the host redistribute headroom than manually rebalance every VM by hand.
  • Mixed workloads with unpredictable peaks, where giving every VM a large ceiling but a modest floor lets bursty VMs borrow from idle ones without you pre-planning exact allocations.
  • Clusters using auto-ballooning with shares to express relative priority — e.g., giving a build server a higher share weight than a rarely-used utility VM so it gets first claim on any spare RAM.

When You Should Turn It Off

Ballooning is a convenience feature for capacity flexibility, not something every VM should run with. Disable it (set balloon: 0, or set Minimum memory equal to Memory in the GUI) in these cases:

  • Databases and other memory-sensitive services. PostgreSQL, MySQL, Elasticsearch, and similar workloads size internal caches and buffer pools based on available RAM at startup. Having the host silently reclaim memory mid-run can degrade performance in ways that are hard to diagnose, or in the worst case trigger the guest's OOM killer against the database process itself.
  • Any VM with PCI passthrough or a vGPU (VFIO mediated device) attached. This isn't a best-practice recommendation — it's a hard technical limitation. Passed-through devices are mapped to fixed guest-physical addresses, so the balloon driver cannot safely inflate or deflate around them. Ballooning simply will not function correctly on these VMs; disable it explicitly rather than leaving it enabled and assuming it's inert.
  • VMs with a hard SLA or predictable capacity planning requirements, where you need to guarantee a VM always has its full configured RAM available rather than relying on the host to grant it under contention.
  • Latency-sensitive workloads where an inflate/deflate cycle mid-operation is an acceptable risk you'd rather not take, even if rare.

A reasonable default policy for a small-to-medium cluster: leave ballooning on for general-purpose Linux app servers and utility VMs, and explicitly disable it for anything running a database, anything with PCI/GPU passthrough, and anything you've promised a fixed amount of RAM to a client or team.

Troubleshooting Common Ballooning Problems

Balloon "actual" value never changes

Almost always a missing or non-running driver in the guest. On Windows, check that both the VirtIO Balloon driver and the balloon service (installed via blnsvr.exe -i from the virtio-win ISO) are present — Device Manager showing the driver isn't sufficient if the service was never installed. On Linux, confirm the module is loaded with lsmod | grep virtio_balloon; if it's missing, check that the VM's Hardware > Memory has the Ballooning Device box checked (it adds the virtio-balloon PCI device the driver needs to bind to).

VM won't start: "not enough memory"

Proxmox reserves the maximum configured memory for a VM at start time for capacity-planning purposes, even though ballooning may let it run comfortably in less once live. If your node's total configured VM memory exceeds physical RAM and you're hitting start failures, either lower some VMs' Memory ceilings, make sure ballooning is actually enabled (not accidentally set to 0) on VMs you intended to overcommit, or add swap as a safety margin — swap should be a backstop for a misbehaving guest, not a substitute for correctly sized ballooning.

Guest's OOM killer is terminating processes

This means the host requested more memory back than the guest actually had spare, usually because Minimum memory was set too low relative to what the workload genuinely needs at idle. Raise the Minimum memory floor for that VM, or disable ballooning for it if the workload can't tolerate any reclaim.

Ballooning shows as active but the graphs look static

If the host isn't under memory pressure and no other VM needs the RAM, there's nothing for ballooning to do — a flat graph at or near the Memory ceiling with light host load is normal, not a fault.

Frequently Asked Questions

Does ballooning require the QEMU Guest Agent?

No. Ballooning uses its own dedicated virtio-balloon device and driver, independent of the QEMU Guest Agent (which handles things like IP reporting, filesystem freeze/thaw for snapshots, and clean shutdown signaling). You can run one without the other, though most production VMs benefit from having both enabled.

Can I change ballooning settings without rebooting the VM?

Yes. qm set changes to memory, balloon, and shares apply live to a running VM. What does require a full shutdown (not just a reboot) is attaching or removing the balloon device itself — for example, going from ballooning fully disabled at VM creation to enabling it later.

Does ballooning work with LXC containers?

No — ballooning is a QEMU/KVM (full VM) feature built around the virtio-balloon device. LXC containers share the host kernel directly and use cgroup memory limits instead, which the host can adjust without any guest-side driver cooperation.

Is it safe to overcommit memory across a whole cluster using ballooning?

It's safe in the sense that it won't crash the host — but ballooning only redistributes RAM that guests are willing to give up. If every VM on a node is simultaneously under real memory pressure, ballooning has nothing left to reclaim, and you'll see guests hit their Minimum memory floor and start swapping or triggering OOM kills internally. Treat ballooning as headroom for typical idle/burst patterns, not as a substitute for having enough physical RAM to cover your VMs' actual peak concurrent demand.

Why does my newly created VM already have ballooning enabled?

The Proxmox GUI enables the Ballooning Device by default for new VMs, with Minimum memory left equal to the configured Memory value until you change it. In that default state there's no effective range for the host to reclaim from, so you won't see any dynamic behavior until you actually lower Minimum memory below Memory.

Summary

Memory ballooning gives Proxmox VE a way to let VMs share physical RAM dynamically instead of locking every VM into a fixed slice of the host's memory. It works through a cooperative virtio-balloon driver in the guest, controlled by three config values — memory, balloon, and shares — that you can set through the GUI's Hardware > Memory dialog or directly with qm set, and it applies live without downtime. It's genuinely useful for homelabs and general-purpose workloads where you want flexible overcommit, but it's the wrong choice for databases, anything using PCI/vGPU passthrough, and any VM where you've committed to a fixed, guaranteed amount of RAM. Knowing which category each of your VMs falls into — and setting balloon accordingly — is a five-minute check that prevents a lot of confusing "why is my VM's memory doing that" troubleshooting later.