Both guest types appear in the same menu, so the choice feels cosmetic. It decides whether a workload can be moved while running, whether it can host a container runtime, how much memory it really costs, and how strong the boundary is between it and its neighbours. One architectural fact generates all of those, and once you have it the decision takes seconds.
Proxmox offers two guest types from the same interface, which invites the assumption that they are two flavours of the same thing. They are not. One shares the host kernel and one brings its own, and nearly every difference that matters in operation follows from that single fact.
The One Difference That Generates the Others
An LXC container is a set of processes running directly on the host kernel, isolated with namespaces and cgroups. A VM is a full machine emulated by KVM, running whatever kernel its disk image contains.
Work through the consequences and you have the entire comparison. A container cannot load a kernel module the host does not have, cannot run a different operating system family, and inherits the host's kernel version including its bugs. In exchange it starts in under a second, consumes memory only for what its processes actually use, and shares the host's page cache.
A VM can run anything, isolates faults at the hypervisor boundary, and can be live-migrated between nodes without interrupting service. It costs a second kernel's worth of memory and a boot sequence.
The Comparison That Matters in Practice
| Property | LXC container | KVM virtual machine |
|---|---|---|
| Kernel | Shared with the host | Its own |
| Guest OS | Linux only, matching host kernel | Any, including Windows and BSD |
| Boot time | Under a second | Seconds to a minute |
| Memory behaviour | Uses what processes use | Reserves what you assigned |
| Live migration | Not supported; restart required | Supported, no service interruption |
| Isolation strength | Namespaces, weaker boundary | Hypervisor, stronger boundary |
| Nested virtualisation or Docker | Awkward, needs relaxed settings | Works normally |
| Backup granularity | Filesystem-level, fast | Block-level image |
The live migration row is the one that changes cluster design. Containers must be stopped to move, so a node you want to patch without downtime should be hosting VMs, or the containers on it must be things that tolerate a restart. Our runbook for Proxmox maintenance without downtime covers working around it.
The Density Argument, and Its Limits
Container memory accounting is genuinely different, not just more efficient. A VM given 4 GB holds 4 GB from the host's perspective, whether or not the guest uses it. A container with a 4 GB limit consumes what its processes touch.
On a host running thirty small services, that difference is the difference between needing one machine and needing three. Ten containers running a web application and its supporting daemons will comfortably fit where four equivalent VMs would not.
The limit is that the saving is real only for workloads that are actually small. A container running a database with a 24 GB buffer pool consumes 24 GB, and you have traded away the isolation and migration properties for nothing. Density is an argument for many small guests, not for large ones.
Privileged, Unprivileged, and the Security Question
Proxmox creates containers unprivileged by default, which maps the container's root to a non-root user on the host. This is the setting that makes container isolation defensible, and turning it off is a bigger decision than the checkbox suggests.
A privileged container's root has a meaningful path to host root if a kernel vulnerability is available, because there is one kernel and it is the host's. So the rule is straightforward: unprivileged unless something genuinely cannot work otherwise, and a workload from a source you do not fully trust belongs in a VM regardless.
Multi-tenancy is the clearest case. If different customers' workloads must not reach each other, the hypervisor boundary is the one to rely on. This is why hosting platforms sell VMs rather than containers, and it is not a marketing decision.
Docker Inside Which One
Running Docker inside an LXC container works and is a recurring source of subtle breakage. It needs nesting enabled, often needs the container privileged or given specific capabilities, and storage drivers behave differently than they do on a normal host. Every Docker upgrade is then a chance for the arrangement to stop working.
Put Docker in a VM. The isolation is correct, the storage driver behaves as documented, and the container runtime is not fighting the container it lives in. The overhead of one extra kernel is trivial next to an afternoon spent on a container runtime that will not start after an update.
The same applies to Kubernetes nodes, for the same reasons plus one more: a kubelet expects to own its node's cgroups and kernel parameters. Our guide to running Kubernetes on Proxmox uses VMs for the nodes deliberately.
A Decision Rule That Holds Up
Use a container for a small Linux service you control, where a restart during maintenance is acceptable and density matters: a reverse proxy, a monitoring agent, a small application server, a development environment, a DNS resolver.
Use a VM for anything non-Linux, anything needing its own kernel or modules, anything running Docker or Kubernetes, anything that must live-migrate for patching, anything belonging to a different tenant, and anything whose data would be painful to lose.
Mixed is the normal end state, and picking per workload rather than standardising on one is the correct answer rather than a failure to decide.
What the Platform Underneath Decides
Both guest types depend on shared storage to survive a node failing, since a guest whose disk lives on one machine cannot be restarted anywhere else.
MassiveGRID runs Proxmox high-availability clustering with automatic failover over Ceph storage that replicates every block three times across independent NVMe drives, so a lost node's guests restart elsewhere with their disks intact. Products are provisioned as VMs, which is the right boundary for tenant isolation, and range from a Linux VPS at per-resource pricing of $2.87 per CPU core, $0.80 per GB of RAM and $0.01 per GB of SSD per month, up to a private cloud where you run your own mix of containers and VMs. Proxmox support starts at $99 per node per month for clusters you operate yourself.
Infrastructure can be ordered across a partner footprint of more than 700 datacenters in 85 metros, 30 countries and six continents, with auto-provisioning in New York, London, Frankfurt and Singapore.