Most “how to pick a VPS” advice stops at the price table. That is the wrong order of operations, because two plans at the same monthly price can differ by an order of magnitude in what they actually deliver once you run a real workload on them. The honest approach is to treat a VPS purchase as a measurement exercise: you get a short provisioning window and, later, a production period, and you want enough data to know whether you bought a fast machine or a cheap one. This evaluation walks through the four dimensions that decide almost all of a plan’s practical value — CPU allocation, RAM guarantees, storage class, and network path — with the specific commands to verify each before you pay for a year. Operational detail matters more than marketing copy here, and a quick read of the hosting reference material on this site helps you frame the numbers you collect.
Start with a baseline you can compare later
Provision the plan you are considering, then run every test on a freshly booted instance before you install anything. A clean baseline is the only way to attribute a slow result to the provider rather than your own stack.
Record, at minimum, the kernel version, the number of vCPUs, the advertised memory, the size of the swap device, and the filesystem type. Save those in a text file next to your benchmark output. When a host silently changes a plan’s shape six months later — and they do — that baseline is the evidence you need.
CPU: allocation model matters more than core count
The spec sheet says “4 vCPU”. It does not say whether those are four dedicated physical cores or four timeslices on a contended core. Steal time is the metric that exposes the difference: it reports how often your vCPU was runnable but the hypervisor scheduled someone else’s work instead.
Install sysstat and sample during your own peak hours, not at 2 a.m.:
mpstat -P ALL 1 30
Sustained %steal under about 2% means the host has headroom. Readings that regularly exceed 5% on a nominally idle box are a warning; anything above 10% means no amount of application tuning will fix the latency. Pair the sample with a single-core stability run, since shared-core plans often show healthy aggregate numbers while individual cores throttle:
sysbench cpu --cpu-max-prime=20000 --threads=1 run
Run it three times and look at the spread between the slowest and fastest result. A spread under 5% suggests consistent scheduling. A spread of 20% or more points to noisy neighbours or aggressive CPU frequency scaling, both of which hurt latency-sensitive workloads far more than throughput-oriented ones.
RAM: guaranteed allocation versus burstable memory
“2 GB RAM” is not a stable quantity on every platform. On some plans the number is a hard reservation; on others a balloon driver can reclaim pages when the physical host comes under pressure. The symptom is a workload that runs perfectly for weeks and then dies with an out-of-memory kill when a neighbour ramps up.
Check what the guest actually sees and whether swap is already engaged at idle:
free -m
cat /proc/meminfo | grep -E "MemTotal|MemAvailable|SwapTotal"
A plan that boots with a swap device already in use advertises more memory than it can deliver. Hold a large allocation for an hour and watch MemAvailable and /proc/vmstat‘s pgscan_direct counter; if direct reclaim climbs while your process is only touching memory it allocated, the host is squeezing you.
| Metric | Healthy reading | What a poor reading implies |
|---|---|---|
%steal (mpstat) |
< 2% at peak | Oversubscribed host |
pgscan_direct growth |
Flat while idle | Memory ballooning |
| 4K random read IOPS | > 15,000 on NVMe | Shared or remote storage |
| Packet loss (mtr) | 0% on first 5 hops | Congested uplink or bad transit |
Storage: verify the tier instead of trusting the label
Storage is where budget plans economise most aggressively, and the marketing label — “SSD” or “NVMe” — tells you very little. What matters for databases and busy web stacks is 4 KB random I/O with queue depth, because that is the access pattern that turns into user-visible latency.
fio --name=randread --rw=randread --bs=4k --iodepth=32 --size=1G --runtime=60 --time_based --group_reporting
fio --name=randwrite --rw=randwrite --bs=4k --iodepth=32 --size=1G --runtime=60 --time_based --group_reporting
Local NVMe on a healthy host should comfortably exceed 15,000 IOPS at this depth and often reaches several times that. SATA-class arrays typically land in the low thousands. If a plan markets solid-state storage but returns fewer than roughly 1,500 IOPS with four-figure write latency, you are probably on a network-attached volume shared across many tenants.
Also confirm two operational details: whether fstrim has run recently, and whether the block device reports a rotational flag of zero. Both are one-line checks that catch mislabelled storage before you migrate production data onto it.
lsblk -d -o NAME,ROTA,MODEL
systemctl status fstrim.timer
Network: measure the path, not the port speed
A “1 Gbps uplink” is meaningless if the transit route to your users is congested or the port is heavily shared. What users experience is the path between their connection and your server, and that is what you should measure.
mtr -rwzc 100 1.1.1.1
iperf3 -c speed.hetzner.de -t 30 -P 4
Read the mtr output for loss at any intermediate hop that persists to the final destination. Loss at a single hop that vanishes later is usually ICMP rate limiting on a router and not a real problem; loss that carries through is. For throughput, ignore the first few seconds and look at the sustained average across thirty seconds, then repeat at a time of day matching your traffic peak.
Read the transfer allowance carefully. Many “unmetered” plans enforce a fair-use cap by port shaping once you cross a threshold, so ask the provider to confirm the number in writing.
Put the numbers into a single scorecard
Once you have the four datasets, resist the temptation to pick the cheapest plan that looks broadly acceptable. Instead, weight each dimension by what your workload actually depends on. A static site is almost entirely network and disk-read bound; a database workload is dominated by random write latency and RAM; a build server cares about sustained single-core performance. Give each dimension a weight, normalise the measured values against the best result in your shortlist, and the decision usually stops being close.
Repeat this process on the provider you choose about a month after go-live. Hosts get busier over time, and a plan that measured well on day one can degrade once the physical node fills up. For more measurement-first walkthroughs of server behaviour, see the technical guides at virtualserversvps.com.



Leave a Reply
You must be logged in to post a comment.