VPS Architecture Explained: Hypervisors, CPU Shares, and I/O Limits

Two VPS plans that both advertise 4 vCPU and 8 GB can perform very differently under load, and the difference is rarely in the headline numbers. It comes from how the host virtualises the CPU, how it schedules your vCPU when the physical machine is busy, and how it connects storage. Understanding the architecture lets you read a spec sheet critically and predict where a workload will stall before you deploy it.

This article walks through the layers from hypervisor to filesystem, with the specific observations you can make on any instance. Where hardware choice matters, compare the tiers listed on the VPS plans page against the explanations below.

Hypervisors: KVM versus container-based virtualisation

KVM is a type-1 hypervisor that runs inside the Linux kernel and gives each guest its own kernel, its own memory space, and full hardware virtualisation for CPU and I/O. Containers on the other hand share the host kernel, which makes them lighter but means your “VPS” is really a namespaced slice of one operating system. OpenVZ and LXC-based hosts commonly oversell memory because unused pages can be reclaimed by the host at any time.

The practical test is quick: run systemd-detect-virt. It prints kvm on a true virtual machine, openvz or lxc on a container. On a KVM guest, cat /proc/cpuinfo shows a named CPU model; on a container, it may show the host’s full CPU list, sometimes with more cores than you paid for. Bare metal access to custom kernels is also a KVM-only feature, which matters if you need DPDK, ZFS, or a specialised network stack.

CPU shares, quotas, and the meaning of “vCPU”

A vCPU is not a physical core. On KVM it is a thread the host scheduler places on a physical core, usually with a CPU share or weight attached. Two guests both requesting full CPU on the same oversubscribed host will each get roughly half, regardless of the advertised count. That is fine for web serving and painful for a build server or a database doing large sorts.

Watch the steal column in top or st in vmstat. Steal time is the fraction of the interval your vCPU was runnable but the host gave the physical core to someone else. Under 1 percent is normal. Sustained values above 5 percent mean you are competing, and above 10 percent means your effective performance is roughly the advertised clock times (1 minus steal). A 2.5 GHz vCPU at 15 percent steal behaves like 2.1 GHz.

Memory: ballooning, overcommit, and the OOM killer

Hosts commonly overcommit RAM and use ballooning to reclaim it: a driver inside your guest inflates a balloon, which the host treats as free memory, reducing what is available to you without any visible error. You experience it as sudden pressure, cache eviction, and eventually the guest OOM killer terminating a process that was doing nothing wrong.

Protect yourself by setting realistic limits. A 2 GB instance with MariaDB and PHP-FPM should not be allowed to reach 1.95 GB of anonymous memory. Configure a swap file of equal size as a cushion, set systemd MemoryMax= on the largest service, and keep vm.swappiness low, around 10, so the kernel prefers dropping page cache over swapping working sets.

Disk I/O: local NVMe, network block storage, and shared arrays

Storage architecture drives more perceived speed than CPU for most workloads. Local NVMe on the same host delivers 200 to 600 microseconds of random read latency and tens of thousands of IOPS. Network-attached block storage (iSCSI or NVMe-oF) adds 0.3 to 1 ms per round trip, which is invisible to a blog and painful for a database doing many small synchronous writes. Shared spinning arrays still exist on cheap plans and can bottom out below 200 IOPS.

Measure before trusting the label. fio --name=randread --rw=randread --bs=4k --iodepth=32 --direct=1 --size=1G gives a clear picture; expect more than 40,000 IOPS on real NVMe and under 5,000 on a modest network volume. Also check whether the plan bills “IOPS” as a hard cap with burst credits, because a host that throttles you at 1,000 IOPS after a five-minute burst will stall a backup job every night at exactly the same time.

Network path: virtual switches, bandwidth, and packet rate

Each guest gets a virtual NIC bridged to a host virtual switch. Throughput is usually capped per instance in software, but packet rate is a separate and often unlisted limit. A 1 Gbps cap sounds generous until you serve 10,000 small HTTP requests per second, where the host’s per-packet overhead or a rate limiter expressed in packets per second becomes the ceiling.

Test with iperf3 for throughput and hping3 or a small load generator for packets per second. Also check whether the advertised bandwidth is shared or dedicated: on some providers the 1 Gbps figure is the whole node’s uplink divided among tenants. If your service is latency sensitive, confirm the data centre region matters more than the port speed; 10 ms of extra distance costs more than 200 Mbps of headroom.

Storage layout: filesystems, trim, and snapshots

Most providers present a raw virtual disk, and you choose ext4 or XFS at install. ext4 is fine for general workloads and handles millions of small files; XFS is better for large files and parallel writes because of its allocation groups. On NVMe, enable discard in fstab or run fstrim weekly, otherwise deleted blocks are never returned to the host and write performance degrades over months.

Snapshots are a host-level feature, not a backup. They capture the disk but not the consistency of your database, so a snapshot taken during a PostgreSQL write can restore to a corrupt state. Use them for fast rollback after a failed upgrade, and pair them with application-level dumps for anything that matters. Check that snapshots live on separate storage; some providers keep them on the same array, which protects against operator error and nothing else.

Reading a spec sheet without being misled

Prioritise in this order: hypervisor type, CPU model and whether cores are dedicated, storage type with measured IOPS, then RAM and bandwidth. A KVM plan with dedicated cores and NVMe will beat a container plan with more advertised vCPU for almost every realistic workload. Ask the provider directly whether CPU is dedicated or shared, and whether memory is ballooned.

Then verify on arrival rather than after launch week. Run lscpu, check steal during a two-core stress-ng run, run the fio test above, and confirm fstrim -v returns a non-zero trimmed byte count. If any of those fail, you have found the gap between the page and the product, and the hosting comparison pages will show which alternatives list the underlying hardware.

What this means for choosing a plan

For a web application, CPU shares and storage latency dominate. For a database, memory overcommit and IOPS matter most. For a VPN or proxy, packet rate and network path decide quality. For a build server, dedicated cores are the only thing that prevents a 10-minute build becoming a 40-minute one. Match the plan to the constraint that binds your workload, not to the largest number on the page.

If you are unsure, start on a mid-tier plan with dedicated cores, measure steal, IOPS, and memory headroom for a week, and size from real data. That approach beats guessing from a specification table, and the VPS catalogue makes it easy to step up a tier once the measurements justify it.

Leave a Reply