LXC Containers vs VMs in Proxmox: When to Use Each

LXC containers vs vms in proxmox

In Proxmox you’ll run both LXC containers and full VMs — the rule I follow is simple: containers for small Linux services, VMs for the firewall, anything non-Linux, and anything that needs hard kernel-level isolation. An LXC container boots in about a second and uses a fraction of the RAM a VM reserves, so the same mini PC that strains at eight services as VMs runs dozens as containers. After years of running a Proxmox host as the spine of my network, here’s how I actually decide.

If you’re earlier in the process, the Proxmox home server guide covers the whole build and the initial setup guide gets you installed. This one is about what to put on the host once it’s running.

What’s actually different under the hood

The distinction is real and it matters. A VM is a full virtual machine: it boots its own kernel, emulates its own hardware, and is isolated from the host at the hardware-virtualization level. It’s heavy — it reserves its RAM, it takes a minute to boot, it carries the overhead of a complete operating system — but it’s also completely self-contained and can run anything, including Windows or a BSD-based firewall.

An LXC container is OS-level virtualization. It shares the host’s Linux kernel and runs as an isolated userspace on top of it. There’s no second kernel, no hardware emulation, almost no overhead. A container boots in about a second, uses a fraction of the RAM, and you can pack a lot of them onto modest hardware. The trade-off is that it must be Linux (it’s sharing a Linux kernel) and the isolation, while strong, isn’t the hardware-level wall a VM gives you.

My default: container first, VM when you must

For a homelab my bias is containers, because most of what a homelab runs is small Linux services and containers let you run far more of them per box. Pi-hole or AdGuard, a reverse proxy, a monitoring agent, a small database, a dozen single-purpose daemons — all containers, all sipping resources. The density is the whole point: on the same mini PC, I’ll fit several times as many LXC services as I would VMs.

Proxmox interface showing a list of lightweight LXC containers and a few virtual machines running side by side on a homelab host

I reach for a VM in a specific set of cases: the firewall (I virtualize OPNsense as a VM with its own NIC), anything that isn’t Linux (a Windows VM, a different OS for testing), anything that needs to load its own kernel modules or run a different kernel than the host, and anything where I want the strongest possible isolation — a service exposed to the internet, or something I simply don’t trust. When in doubt about isolation, a VM is the safer wall.

Privileged vs unprivileged containers — the bit that trips people up

Here’s the nuance that catches new users. LXC containers come in two flavors. Unprivileged containers (the default, and the right default) map the container’s root user to an unprivileged user on the host — so even root inside the container isn’t root on the host. This is the secure choice and what you should use for almost everything.

Privileged containers don’t do that mapping; container root is effectively host root. You only need them for specific cases — certain device-passthrough scenarios, some older software — and you should treat them with the same caution you’d give a service running as host root, because that’s essentially what they are. My rule: unprivileged by default, privileged only when something genuinely won’t work otherwise, and then only for things I trust. If you find yourself reaching for a privileged container for an untrusted service, that’s a sign the workload should be a VM instead.

Passing hardware into containers and VMs

Both can access host hardware, but differently. Containers can bind-mount host directories and pass through devices like a GPU for transcoding relatively cheaply, because they share the kernel — this is why a media transcoder is often a container. VMs use full PCIe passthrough, handing an entire physical device to the guest, which is heavier but gives total isolation and is the right approach when a device must belong to exactly one guest with no sharing. If you need a GPU handed wholesale to a single VM, that’s passthrough territory, and it’s its own finicky topic — I cover it in the Proxmox GPU passthrough guide.

Close-up of a homelab mini PC with NVMe storage running multiple isolated services as containers and virtual machines

Side by side

FactorLXC ContainerVirtual Machine (KVM)
OverheadMinimal — shares host kernelHigher — full OS and kernel
Boot timeAbout a secondTens of seconds to a minute
RAM useLow, shared more gracefullyReserved per VM
OS supportLinux onlyAny OS — Linux, Windows, BSD
IsolationStrong (use unprivileged)Strongest — hardware-level
Density per hostVery highLower
Best forSmall Linux services, most of the labFirewall, Windows, untrusted or exposed services

Snapshots, backups, and migration behave differently

One more thing that shapes the choice: how each behaves operationally. Both VMs and containers can be snapshotted and backed up in Proxmox, but containers are lighter to back up (smaller, faster) which, multiplied across a few dozen of them, keeps your backup window short. VMs back up larger images but capture the entire machine state including the kernel, which is exactly what you want for something like the firewall.

Live migration — moving a running guest to another node without downtime — works for VMs cleanly. Containers can be migrated too, though historically with more constraints. For a single-host homelab none of this matters yet, but the moment you add a second node and start thinking about moving things around, VMs are the more flexible unit. It’s a reason some people deliberately keep a critical service as a VM even when a container would technically do — they want the migration story.

Common mistakes I see

The two errors that show up again and again. First, reaching for a privileged container to make something “just work” instead of figuring out why the unprivileged one failed — that’s how people quietly run untrusted code with host-root equivalence. If it won’t run unprivileged, ask whether it should be a VM. Second, running everything as VMs out of habit, usually from an ESXi background, and then wondering why a perfectly good mini PC is full at eight services. Containers exist precisely to solve that, and leaning into them is the single biggest density win on the platform.

A practical sorting rule

When a new service lands on my “to host” list, I run it through three questions. Is it Linux? If no, it’s a VM. Does it need hardware-level isolation — is it exposed to the internet or untrusted? If yes, lean VM. Is it a normal Linux daemon I trust? Then it’s an unprivileged container, and that covers the large majority of a homelab. This little decision tree keeps the host dense where density is safe and isolated where isolation matters.

That balance — a handful of VMs doing the heavy, isolated jobs and a swarm of lightweight containers doing everything else — is exactly what makes Proxmox such a good fit for home, and it’s a capability a VM-only platform like ESXi simply doesn’t offer. I lay out that platform comparison in Proxmox vs VMware for the homelab. Once you’ve sorted VMs versus containers, the next decisions are storage and networking — both covered in the main Proxmox guide, alongside the homelab network builds overview for the bigger picture.

Frequently Asked Questions

Should I use LXC containers or VMs in Proxmox?

Use lightweight LXC containers for the many small Linux services that make up a homelab, since they share the host kernel, boot in about a second, and use far less RAM, letting you run many more per box. Use a full VM for your firewall, anything that is not Linux such as Windows, anything that needs its own kernel, and anything requiring the strongest isolation like an internet-exposed service. Most homelabs end up with a few VMs and a swarm of containers.

Are LXC containers in Proxmox secure?

Yes, when you use unprivileged containers, which is the default and recommended choice. An unprivileged container maps its root user to an unprivileged user on the host, so even root inside the container is not root on the host. Privileged containers remove that mapping and should only be used for specific cases you trust, since container root effectively becomes host root. For untrusted or exposed services, a full VM gives stronger hardware-level isolation.

What is the difference between a privileged and unprivileged container?

An unprivileged container maps the container’s root user to a non-root user on the host, so a compromise inside the container does not give host root. A privileged container does no such mapping, meaning container root is effectively host root. Unprivileged is the secure default for almost everything; privileged is only for narrow cases like certain device passthrough or older software, and only for workloads you trust.

Can LXC containers use less RAM than VMs?

Yes, significantly. A VM reserves its allocated RAM and carries the overhead of a full operating system and kernel. An LXC container shares the host kernel and only uses the memory its processes actually consume, sharing it more gracefully with the host. This is why you can run several times as many containers as VMs on the same hardware, which is the main reason containers are the default for most homelab services.

Why run the firewall as a VM instead of a container?

A firewall benefits from hardware-level isolation and often needs to load its own kernel modules or run a non-Linux base, which an LXC container sharing the host kernel cannot do. Running it as a full VM with its own dedicated network interface gives complete separation from the host and the other guests, which is exactly what you want for the device guarding your entire network.

Leave a Comment

Your email address will not be published. Required fields are marked *