Interpreting VPS Benchmarks: Reading Latency Percentiles, CPU Steal and iowait

A sysbench CPU score or a single dd throughput number tells you almost nothing about how an instance will behave under production load. Two VPS nodes can return identical benchmark figures while one delivers steady 2 ms responses and the other stutters every few seconds. The difference lives in the distribution of latency and in the contention counters the headline number quietly averages away. This article is about reading results, not generating them.

Average Latency Is a Lie

When you run a disk benchmark and it reports an average latency of 1.2 ms, ask where the worst 1% landed. On shared storage the mean is dominated by fast cache hits while the tail — p95, p99, p99.9 — is what your users actually feel when a query misses the cache. Always collect percentiles. With fio this means adding --lat_percentiles=1 and reading the completion-latency table, not just the clat mean. A disk that shows 0.8 ms average with a 40 ms p99 will produce visible TTFB spikes that a mean-based evaluation completely misses.

CPU Steal: The Invisible Tax

Inside a virtual machine, %steal in top or the st column in vmstat reports time your vCPU was runnable but the hypervisor scheduled another guest instead. A single-digit steal is normal. Sustained steal above 5–10% means you are paying for CPU you cannot use — a noisy-neighbour problem no amount of guest tuning can fix. Capture it over time, because steal is bursty: a one-minute sample may show zero while the hourly average is 15%.

vmstat 5 12 | awk 'NR>2 {print $15, $16, $17}'   # us sy st
sar -u 1 30 | tail -5

iowait Is Not “Disk Is Slow”

High iowait only means the CPU had nothing else to run while a request was outstanding. On a single-vCPU instance with a well-behaved workload, iowait can be high simply because there is no other work to schedule. The useful signal is the combination of iowait with device-level latency from iostat -x: look at aqu-sz (average queue depth) and await per device. Rising queue depth alongside rising await means genuine saturation; rising iowait with flat await usually means the workload is simply serialized and under-utilizing the CPU.

Building a Comparison That Means Something

To compare instances fairly, run identical workloads at identical concurrency for several minutes each, ideally at the same time of day, and record the full percentile distribution plus steal. Repeat runs matter: a single sample cannot distinguish a consistently fast instance from a lucky one. If you are evaluating providers before committing, this overview of how VPS performance is provisioned explains the underlying storage and CPU allocation models that produce these differences in the first place.

A Minimal Interpretation Checklist

Before you declare an instance fast or slow, confirm you have: retrieval and completion latency percentiles rather than means; a steal figure captured over at least an hour; device queue depth during the test; and repeatability across at least two runs. A benchmark that satisfies all four is worth ten that report only an average. For workloads that are memory-bound rather than I/O-bound, verify your swap and reclaim behaviour as well — a fast disk with constant page reclaim will still benchmark poorly. For deeper tuning context, the site’s technical guides cover the kernel knobs that move these numbers.

Benchmarks are not scores to maximise; they are diagnostic readings to interpret. Once you read the tail and the contention counters, the number stops being ambiguous and starts telling you whether the instance suits your workload.

Leave a Reply