Hello and welcome back to Architecting Zero Downtime Infrastructure! It’s fantastic to have you here for episode eleven. Today, we’re diving into a topic that I find is so often overlooked but holds the key to incredible gains: performance tuning Proxmox.
Let’s be honest, you’ve invested in some solid hardware. But are you truly getting every ounce of performance out of it? A standard Proxmox installation is a marvel of stability right out of the box. It’s designed to be a reliable workhorse for the widest possible range of hardware. Think of it like a new car straight from the factory—it runs beautifully, but it’s tuned for universal appeal, not for the specific track you’re racing on. The real power, the raw speed, and unshakeable stability that you paid for are often waiting just beneath that surface of default settings.
Our mission today is to move beyond those defaults and unlock that hidden potential. And this isn’t just for folks running massive enterprise clusters! These principles will enhance the speed and stability of any system, from a single-node homelab to a multi-rack deployment. After all, performance isn’t just about flashy benchmark numbers; it’s a cornerstone of reliability and a critical component of any serious zero-downtime philosophy.
So, let’s roll up our sleeves and get started!
The Heart of the System: CPU Tuning
We’ll begin with the very heart of your system: the CPU. When you configure a virtual machine, one of the most impactful settings you can touch is the CPU Type. By default, it’s set to something very generic for compatibility.
My unbreakable rule for any performance-sensitive workload is to change this setting from the default to host. It’s a simple, powerful change with a direct, tangible payoff. Setting the type to host essentially passes through your physical CPU’s exact feature set to the virtual machine. This allows your applications to leverage all the modern instruction sets they were designed for, like AVX. It’s like telling your VM, “Stop pretending to be a generic processor and use the real, high-performance engine we have right here!”
For mission-critical systems, we can go even further with CPU pinning and NUMA awareness:
- Pinning: This is where you assign a VM’s virtual cores to specific physical cores on your host. It prevents the hypervisor’s scheduler from bouncing the workload between different cores. Why does this matter? Every time a process moves, it can lose its cached data, forcing it to fetch from much slower main memory. Pinning ensures consistency and dramatically reduces latency. It’s a must for applications like databases or real-time processing.
- NUMA (Non-Uniform Memory Access): If you’re running a server with multiple physical CPU sockets, respecting NUMA is not just a tweak; it’s fundamental. It ensures that a VM running on Processor A uses the memory directly attached to Processor A, avoiding the much slower interconnect path to Processor B’s memory. For demanding databases, getting this right can be the difference between a system that flies and one that mysteriously crawls under load.
Don’t Let Your Memory Float Away
Next up, let’s talk about memory. One feature you’ll see enabled by default is memory ballooning. The idea is clever: the host can “reclaim” unused memory from a guest VM to give to another that needs it, allowing you to run more VMs on the same hardware. This is perfectly fine for development machines or less critical services.
However, for a production database, a critical application server, or anything where memory access latency matters, my strong recommendation is to turn ballooning off. Give the VM a fixed, guaranteed slice of RAM. This prevents the host from trying to negotiate memory back from the guest right when it’s under heavy load, which can introduce unpredictable latency spikes. You trade a little bit of density for a whole lot of predictable performance.
For a more advanced boost, I often look at enabling HugePages. Let me paint a vivid picture. Normally, the operating system manages memory in tiny 4-kilobyte chunks, like a warehouse manager tracking millions of individual small boxes. It’s a lot of overhead! HugePages allows the system to manage memory in much larger blocks—often 2 megabytes or even 1 gigabyte. It’s like switching from small boxes to massive shipping containers. The CPU has far less administrative work to do tracking memory locations, freeing it up to focus on your application’s actual work. For any workload with a large memory footprint, this is a change you will absolutely feel.
Taming the I/O Beast: Storage Optimization
If there’s one place where performance bottlenecks love to hide, it’s in storage I/O. For the underlying storage on a single host, I find ZFS is a fantastic choice for its incredible data integrity features and solid performance, while LVM-Thin is great for its speed and simplicity. (Ceph, of course, is the go-to for clustered environments, but that’s a whole other episode!)
But the real tuning often happens on the virtual disk itself. A critical choice you’ll make is the cache setting. You’ll see two main options: writethrough and writeback.
- writethrough is the safe default. It confirms a write only after the data is physically on the disk.
- writeback is where the speed is. It confirms a write as soon as it hits the host’s super-fast RAM cache. The risk? If your host loses power before that cache is flushed to disk, you lose that data.
My personal rule of thumb is to use writeback, but only if you have your host on a reliable battery backup (UPS). It’s a calculated risk for a massive reward in write performance. And while you’re in those settings, enable the modern io_uring option for I/O threading. It’s a genuine leap forward for asynchronous I/O and can really let your modern SSDs stretch their legs.
Building a Multi-Lane Highway for Your Network
Networking is an area where one simple choice can have an absolutely massive impact. When you create a VM, Proxmox has to give it a virtual network card. The default is often a fully emulated card, like an Intel e1000. It’s a marvel of compatibility—it will work with almost any guest OS, old or new. But it is slow because the host has to pretend to be a physical piece of hardware.
For any modern guest operating system (which is likely everything you’re running), you should be using VirtIO. This is a paravirtualized driver, meaning it was designed from the ground up for virtualization. The guest OS knows it’s in a VM and uses a highly efficient, direct communication path to the host. The performance difference isn’t just a few percentage points; it’s orders of magnitude faster. This should be your non-negotiable standard.
But here’s the pro-level trick: for any VM with multiple vCPUs, you must enable the Multi-Queue option. Without it, all network processing for that entire VM is crammed through a single virtual CPU core. A busy web server or firewall can easily overwhelm that one core, creating a completely artificial bottleneck. Enabling multi-queue allows the network workload to be distributed across several vCPUs in parallel. You’re effectively turning a single-lane country road into a multi-lane superhighway for your network traffic, preventing jams and dramatically increasing your total throughput. This change is transformative.
The Other Half of the Equation: Guest OS Tuning
Tuning the host is only half the battle. The performance you actually experience depends just as much on what’s happening inside the guest operating system.
- Install the Guest Agent and Drivers: The very first thing I do on any new VM is to ensure the QEMU guest agent and the correct VirtIO drivers are installed and running. Without these, the host and guest can’t communicate efficiently. You simply won’t get the storage or network speeds we’ve worked so hard to enable.
- Use noatime: This is a subtle but powerful tweak. In your guest’s filesystem settings (/etc/fstab on Linux), add the noatime mount option. By default, the OS performs a write operation every single time a file is read just to update its last-accessed timestamp. On a busy server, this can eliminate thousands of completely unnecessary I/O operations per second.
- Check Partition Alignment: This is a small detail that can yield a very real improvement in disk throughput. Making sure your partitions are correctly aligned with the underlying storage blocks prevents the drive from having to do extra work on every read and write. Most modern installers handle this correctly, but it’s worth verifying.
Going Deeper: Tuning the Proxmox Host Kernel
For those who want to wring every last drop of performance from their hardware, we can go a layer deeper and tune the Proxmox host kernel itself.
- CPU Governor: The default governor, ondemand, saves power by scaling the CPU’s frequency up and down. This is great for a desktop, but it can introduce tiny bits of latency as the CPU ramps up. For systems where consistent, predictable speed is critical, I set the governor to performance. This pins the CPUs at their maximum frequency, ready to go at a moment’s notice.
- I/O Scheduler: With today’s lightning-fast NVMe SSDs, the traditional I/O schedulers can sometimes become a bottleneck themselves. What you’ll often find works best is to set the I/O scheduler to none or mq-deadline. This essentially gets out of the way and lets the high-performance drive’s own internal logic manage its I/O queue much more efficiently.
KVM vs. LXC: The Performance Trade-Off
No performance discussion is complete without touching on the choice between a full KVM virtual machine and a lightweight LXC container. The answer from a pure performance perspective is clear: containers are significantly faster.
Let me break it down. A KVM machine is like building a complete, separate house. It has its own foundation, its own walls, its own roof (the OS kernel). This creates a strong security boundary, but all that structure comes with overhead. An LXC container, on the other hand, is like a well-insulated apartment in a larger building. It shares the building’s foundation and structure (the host’s kernel) but has its own secure living space.
Because it shares the host kernel, a container’s performance is incredibly close to running on bare metal. For applications like web servers, databases, or microservices where I need maximum efficiency, containers are my go-to choice. But when iron-clad isolation is the top priority—for multi-tenant services or running untrusted code—the security boundary of a full VM is the only correct answer. It’s a classic trade-off: near-bare-metal speed versus hardened isolation.
You Can’t Improve What You Don’t Measure
All of these changes are powerful, but they mean very little if you can’t prove their impact. This is where my most important rule comes into play: adopt a scientific approach.
Before you change a single setting, establish a baseline. For storage, my go-to tool is fio, which can simulate real-world I/O patterns. For networking, iperf3 is perfect for measuring raw throughput.
My process is rigid, but it works:
- Run the benchmark and document the baseline numbers.
- Make one single change. Just one.
- Run the exact same benchmark again.
- Document the new result.
This discipline is what separates professional tuning from just guessing. It turns your assumptions into validated, quantifiable gains and ensures you’re actually making things better, not worse.
Bringing It All Together
Wow, we’ve covered a lot of ground today! We’ve walked through the full stack, from the host’s CPU and memory, down into the nitty-gritty of storage and networking, and finally into the guest OS itself.
What I truly hope you take away from this is that exceptional performance is never an accident. It’s the direct result of active, methodical tuning. It’s this deliberate process that transforms a standard setup into a truly high-performance, resilient system—one that you can count on when it matters most.
I hope you can join me next time for Episode 12, where we’ll be tackling a fascinating topic: “The Hidden Costs of ‘Free’: Calculating TCO for Open-Source Hypervisors”. We’ll dig into whether “free” software is truly free once you account for support, expertise, and operational effort. It’s a critical calculation for any business.
As always, thank you for your time and attention today. If you have any questions or your own favorite tuning tips, please share them in the comments below! I’d love to hear from you.

Leave a Reply