← Back to news

Running MicroVMs in Proxmox VE, the Easy Way

taoofmac.com|167 points|24 comments|by zdw|Jun 19, 2026

Simplifying MicroVM Deployment in Proxmox VE

By Rui Carmo (Tao of Mac) Originally published June 18, 2026

I have spent years managing a diverse Proxmox cluster. My hardware spans a massive spectrum: from a baseline "torture device" (an Atom x5-Z8350 with only 2 GB of RAM, currently retired) to my primary homelab powerhouse, borg, an i7-12700 equipped with 128 GB of RAM.

Driven by the current trend of agentic sandboxes and my own work on agentbox, I grew weary of the eternal compromise trade-off between the lightness of LXC containers and the robustness of full virtual machines. To solve this, I developed pve-microvm. This Debian package integrates QEMU's microvm machine type directly into Proxmox VE as a first-class managed guest.

What started as a simple tool has evolved significantly. It now includes a specialized kernel, patches for Perl internals to enable Web UI integration, and support for 21 different guest operating systems—ranging from Debian and NetBSD to the esoteric Plan9 (which, surprisingly, works perfectly).

Finding the "Goldilocks" Zone

Currently, pve-microvm is my primary choice for hosting Caddy reverse proxies, Gitea, mini-firewalls, and the AI agent assisting with this article. To understand why, we have to look at the standard Proxmox offerings:

  1. LXC Containers: These are incredibly efficient and start instantly because they share the host kernel. However, they lack true isolation; a single kernel exploit can compromise the entire host. Furthermore, nesting Docker inside LXC often requires frustrating fuse-overlayfs configurations.
  2. Full VMs: These provide strong hardware isolation via KVM/VT-x. However, they are "sleepy." They must boot through SeaBIOS or OVMF, slog through GRUB, and probe a massive array of emulated legacy hardware (PCI bridges, VGA, IDE controllers). This results in a 5–10 second boot time and wasted memory for emulated chipsets.

I wanted the security of a VM combined with the velocity of a container. QEMU's microvm type—designed for Firecracker-style workloads—achieves this by stripping away the legacy bloat.

Comparison of Virtualization Methods

FeatureLXC ContainerStandard VMMicroVM
IsolationProcess-level (Shared Kernel)Hardware-level (KVM)Hardware-level (KVM)
Boot SpeedInstantSlow (510s\approx 5\text{--}10\text{s})Ultra-Fast (<300ms< 300\text{ms})
OverheadMinimalHigh (Emulated Chipset)Very Low
Docker NestingComplex/DifficultNativeNative

"The goal was to achieve a sub-300ms boot to a fully networked guest with a QEMU agent, all while maintaining a hardware isolation boundary."

Technical Implementation: Under the Hood

The pve-microvm package functions by patching the qemu-server Perl modules during installation. When a VM configuration is set to machine: microvm, the standard config_to_command function is intercepted by MicroVM.pm. This generates a streamlined QEMU command line:

qemu-system-x86_64 -M microvm,x-option-roms = off,pit = off,pic = off, \
isa-serial = on,rtc = on,acpi = on,pcie = on \
-kernel /usr/share/pve-microvm/vmlinuz \
-initrd /usr/share/pve-microvm/initrd \
-append "console=ttyS0 root=/dev/vda rw quiet" \
-device virtio-blk-pci-non-transitional,drive = drive-scsi0 \
-device virtio-net-pci-non-transitional,netdev = net0 \
...

The guest is stripped down to a single serial console (compatible with PVE's xterm.js), virtio block devices, and a virtio network interface. I opted for PCIe transport with non-transitional virtio devices rather than the original MMIO transport for specific compatibility reasons.

Package Components

The installation provides several key assets:

  • Custom Kernel: A lean 12MB Linux 6.12.22 kernel. It uses x86_64_defconfig with a minimal overlay for virtio, vsock, virtiofs, 9p, and Docker-essential modules (overlay, veth, bridge, netfilter, BPF).
  • Optimized Initrd: A 1MB image that handles device probing and switch_root in roughly 150ms.
  • pve-microvm-template: A tool to generate root filesystems from 12 OCI base images (with optional Docker, SSH, and guest agents).
  • pve-oci-import: A utility to pull OCI images directly into PVE disks.
  • Web UI Enhancements: Adds a "Create μ\muVM" button, a machine type selector, and a distinct amber bolt icon in the resource tree.
  • pve-microvm-early.service: A systemd service ensuring patches are applied before pvedaemon starts, which is vital for VMs set to onboot=1.

The Boot Sequence

Speed in booting is essentially the art of subtraction. By removing the firmware and bootloader stages, the μ\muVM bypasses the most time-consuming parts of the startup process.

Performance Metrics

The results are stark. For a NetBSD guest (SmolBSD) using virtio-mmio, the boot time is a staggering 31ms. For a full Debian installation including Docker and the QEMU agent:

  • First Boot: <8s< 8\text{s} (mostly due to apt installations).
  • Subsequent Boots: Tboot300msT_{boot} \approx 300\text{ms}.

MicroVM Boot Timeline


A Note on the "Rabbit Hole": While exploring SmolBSD support, I discovered a nuance regarding transports. While Linux guests in this setup use PCIe, SmolBSD utilizes virtio-mmio. This is because the QEMU microvm machine type supports two different transport methods for its virtio devices: the bar... (text ends)