Running MicroVMs in Proxmox VE, the Easy Way
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:
- 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-overlayfsconfigurations. - 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
| Feature | LXC Container | Standard VM | MicroVM |
|---|---|---|---|
| Isolation | Process-level (Shared Kernel) | Hardware-level (KVM) | Hardware-level (KVM) |
| Boot Speed | Instant | Slow () | Ultra-Fast () |
| Overhead | Minimal | High (Emulated Chipset) | Very Low |
| Docker Nesting | Complex/Difficult | Native | Native |
"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_defconfigwith a minimal overlay forvirtio,vsock,virtiofs,9p, and Docker-essential modules (overlay,veth,bridge,netfilter,BPF). - Optimized Initrd: A 1MB image that handles device probing and
switch_rootin 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 VM" 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 beforepvedaemonstarts, which is vital for VMs set toonboot=1.
The Boot Sequence
Speed in booting is essentially the art of subtraction. By removing the firmware and bootloader stages, the VM 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: (mostly due to
aptinstallations). - Subsequent Boots: .
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)