Tüm sistemler çalışır durumda 8 kabul edilen kripto paralar · Monero hoş karşılanır KYC'siz politika
KernelVPS

Benchmarking

How to Benchmark a VPS: CPU, Disk, Network and Steal Time

A plan page is a promise. A benchmark is the receipt. Here is how to measure the four things that actually decide whether a server is fast — and how to tell an honest host from an oversold one inside the first hour.

Infrastructure16 min okumaKernelVPS ekibi

How to Benchmark a VPS: CPU, Disk, Network and Steal Time

Two servers with identical spec sheets — same vCPU count, same RAM, same NVMe — routinely differ by a factor of three on real work. The spec sheet describes what was allocated. It says nothing about how many other tenants were allocated the same silicon, whether the disk is a local drive or a network volume three switches away, or whether your vCPU spends a fifth of every second waiting for a hypervisor that promised it to somebody else. Benchmarking is how you find out, and the whole sequence takes about twenty minutes.

The four measurements that decide a server

Everything worth knowing about a machine's speed falls into four buckets. Most published comparisons measure the first and the last, skip the two in the middle, and then wonder why the fast-looking server feels slow.

Sequential CPU

How fast a single thread runs. It sets the ceiling for a web request, a query plan, a build step. Most applications hit this wall long before they hit the one made of core counts.

Contention

How much of your allocated CPU another tenant is actually consuming. Invisible on a spec sheet, measurable in one command, and the entire difference between two identical-looking plans.

Storage latency

Not how many IOPS the array can do in aggregate, but how long one small synchronous write waits. That is what a database commit and a session save sit on.

Network path

Throughput in both directions, plus the route and the packet loss between your instance and the people who use it. A port speed is a claim; a path is a measurement.

Before measuring any of them, spend two minutes establishing what you were actually sold. It changes how you read every number that follows.

Before the first test: find out what you actually bought

A four-core container under a CPU quota and a four-core KVM instance with dedicated threads answer the same command with very different numbers, and only one of the two is what most plan pages imply. Establish which you have before you start drawing conclusions from throughput figures.

  1. 1

    Identify the virtualization

    systemd-detect-virt prints kvm, lxc, openvz or none. KVM is full virtualization and none is bare metal. lxc and openvz mean you share a kernel with other tenants: you cannot load modules, cannot run your own kernel, and are usually subject to a limit the guest cannot see. That distinction matters more than any two-dollar difference in monthly price.

  2. 2

    Read the CPU you were given

    lscpu shows the model, the thread count, the hypervisor flag and the cache sizes. grep -m1 'model name' /proc/cpuinfo names the physical part, which tells you the generation you are actually renting rather than the one in the marketing copy. Write it down; it is the context for every CPU number below.

  3. 3

    Look for a hidden cap

    On cgroup v2, cat /sys/fs/cgroup/cpu.max prints a quota and a period. A value of max 100000 means uncapped; 200000 100000 means you have two cores' worth no matter how many you can see. A guest that reports eight cores and is capped at two produces a perfectly normal single-thread score and an all-core score that stops scaling at three.

  4. 4

    Confirm the rest of the inventory

    nproc, free -h, lsblk and ip -br a take five seconds between them and catch the honest mistakes: the disk that is 40 GB instead of 60, the missing IPv6 block, the second address that was never attached.

Do all of this on a fresh instance, before you install anything on it. Once the box has a database and a workload, every benchmark measures the workload as much as the hardware, and you will never get a clean baseline again.

The rules that make a benchmark mean something

Most published VPS benchmarks are worthless, and for a boringly consistent reason: one run, on one day, with the best number kept. A shared machine does not have a performance level. It has a distribution, and the distribution is the product you are buying.

  • Run every test at least three times and keep the median, not the best. The best number tells you what the hardware can do when nobody else wants it. The median tells you what you bought.
  • Test at two different hours — one in the local afternoon of the region, one in its quiet early morning. If the two disagree by more than roughly twenty percent, the node is contended, and the afternoon figure is the one that describes your life.
  • Give every test at least sixty seconds. Short bursts hide throttling: plenty of providers allow full speed for the first ten to thirty seconds and then quietly apply a credit system.
  • Pin the tool versions. sysbench 1.0.20 and sysbench 1.1 do not produce comparable numbers, and neither do fio builds with different IO engines. Record the version next to every result or the comparison means nothing.
  • Benchmark an idle box. No package manager running, no backup job, no monitoring agent you forgot about. uptime should show a load average near zero before you begin.
  • Note the date, the region and the plan alongside the numbers. Six months from now you will want to know whether the node got slower or you simply landed on a different one.

Sustained full-load loops on shared infrastructure look exactly like abuse to an automated system. Reasonable benchmarking is permitted by almost every acceptable use policy; a week of pegged cores is not. Run the tests for as long as you need and then stop.

CPU: single-core, all-core, and the gap between them

Two numbers matter here, and the relationship between them matters more than either one alone. Single-thread throughput sets the ceiling for anything sequential. All-thread throughput sets the ceiling for anything parallel. An instance with genuinely dedicated threads scales almost linearly between the two. An oversold one does not, and the ratio is where it gives itself away.

  1. 1

    Measure one thread

    sysbench cpu --cpu-max-prime=20000 --threads=1 --time=60 run. Record the events per second. This is your reference for everything sequential — a PHP request, a single query, the front end of a compiler — and it is the number that a higher clock actually buys you.

  2. 2

    Measure every thread

    Repeat with --threads=N, where N is the core count you were sold. On dedicated threads the result lands close to N times the single-thread figure. If four threads deliver less than two and a half times one thread, the cores are shared, capped, or both.

  3. 3

    Cross-check against real work

    openssl speed -evp aes-128-gcm exercises the AES-NI path that TLS actually uses, and 7z b reports a compression rating that stresses cache and memory latency rather than raw arithmetic. When two tools disagree wildly, one of them has usually hit a limit the other did not.

Absolute values only mean something against a reference you trust, so build one: run the same commands on a machine you already know — your laptop, an existing server — and compare. A current EPYC or Ryzen core sits in roughly the same class as a good desktop core from the last few years. If a premium-priced VPS scores half of a four-year-old laptop on a single thread, you are on an old platform, a contended one, or both.

Near-linear scalingAll-core lands close to N times single-core. Dedicated threads, low contention. This is what a KVM instance on /vps or a machine from /dedicated should look like, and it is the shape worth paying for.
Scaling stops earlyFour threads give three times one thread; eight threads give three and a half. Either a cgroup quota nobody mentioned, or real neighbours competing for the same physical cores. Check cpu.max first, because that one is free to fix.
Low single-core, healthy all-coreAn older, wider platform — many slow cores. Fine for parallel batch work and poor for a web application, where one request is one thread and the user waits on it.
Both numbers swing between runsContention, not capability. Re-run at a different hour before concluding anything. A twenty percent swing is ordinary; a two-fold swing is a different server pretending to be the same one.

vCPU counts are not comparable across providers and never have been. One provider's vCPU is a dedicated SMT thread; another's is a slice of a core shared with eleven other tenants. Events per second is comparable. Insist on the measurement, not the label.

Steal time: the number that exposes an oversold host

Steal time is the share of time your virtual CPU was ready to run and could not, because the hypervisor was running somebody else instead. It is the most direct measurement of overselling available to a guest, it costs one command, and almost nobody looks at it.

  1. 1

    Watch it live

    vmstat 1 10 prints a column headed st. top shows the same value as %st on the CPU line. Both are percentages of total CPU time, averaged across all of your cores, which means a small figure spread across many cores is still a large amount of missing work.

  2. 2

    Break it down per core

    mpstat -P ALL 1, from the sysstat package, shows %steal for each vCPU separately. Steal concentrated on one core is usually a scheduling artefact. Steal spread evenly across all of them means the node itself is oversubscribed.

  3. 3

    Measure it under load, never at idle

    An idle guest steals nothing, because it asks for nothing. Run the all-core sysbench test in one terminal and vmstat 1 in another; the steal figure during that minute is the one that describes your server.

0 to 0.5 percentHealthy. The node has headroom and you are getting the cycles you pay for. This is the normal reading on a properly packed host.
0.5 to 2 percentOrdinary on a busy shared node. Visible only in latency-sensitive work, and not worth a support ticket on its own.
2 to 10 percentOversubscribed. You are losing a measurable slice of every core and your tail latency is paying for it. Worth raising with the provider — with the numbers attached, because a reading is an argument and a complaint is not.
Above 10 percentYou are renting a queue, not a core. No amount of application tuning fixes this, because the cycles are being spent on someone else's workload. Move.

One honest caveat: some hypervisors do not report steal to the guest at all, and a container does not report it in any meaningful way. Zero steal on an OpenVZ or LXC instance is not evidence of a quiet node — it is evidence that the number is unavailable. Where steal is missing, measure variance instead. Run the same sixty-second CPU test ten times in a row and look at the spread: a machine that returns the same figure every time has the cycles, and a machine whose figure wanders by thirty percent is sharing them, whatever it does or does not report.

Disk: latency is the number, not IOPS

Storage is where VPS benchmarks go most wrong, because the two habits everybody has — running dd, and quoting a headline IOPS figure — both measure something other than what a real workload feels.

dd if=/dev/zero writes a stream of zeros. On thin-provisioned, compressing or deduplicating storage, zeros are close to free, so the resulting number describes a compression algorithm rather than a drive. Without oflag=direct it also writes into the page cache and reports the speed of your RAM. It is a fine way to confirm that a disk exists and a poor basis for deciding whether to pay for it.

Use fio instead, and read the latency percentiles rather than the headline. A database commit does not care that the array can do four hundred thousand IOPS in aggregate. It cares how long one fsync takes at the ninety-ninth percentile, on a busy evening, while your neighbours are also committing.

  1. 1

    Random read — the general-purpose number

    fio --name=randread --filename=fiotest --size=4G --rw=randread --bs=4k --ioengine=libaio --direct=1 --iodepth=32 --numjobs=4 --runtime=60 --time_based --group_reporting. Record the IOPS and, more importantly, the clat percentiles it prints underneath them.

  2. 2

    Random write — the honest one

    The same command with --rw=randwrite. Writes are where shared storage and cheap consumer drives come apart, and where a provider's caching layer either saves them or does not. Expect a gap between read and write figures; expect a chasm only on bad storage.

  3. 3

    Commit latency — the one that decides your database

    fio --name=fsync --filename=fsynctest --size=1G --rw=write --bs=4k --ioengine=sync --fdatasync=1 --runtime=60 --time_based. The fsync latency percentiles are, for anything transactional, the single most important storage number on the page. Enterprise drives with power-loss protection answer in microseconds; a network volume answers in milliseconds.

  4. 4

    Sequential throughput — last, and least

    Add --rw=read --bs=1M --iodepth=16 --numjobs=1 to learn what a restore or a large backup will do. This is the number providers advertise and the one that matters least on an ordinary day.

  5. 5

    Clean up after yourself

    Delete the test files when you are done. fio writes real data, and a --size chosen carelessly will fill a 20 GB plan while you are still reading the output.

Local NVMe, uncontendedRandom 4k reads into the six figures, p99 read latency comfortably under a millisecond, and fsync latency in the tens to low hundreds of microseconds on drives with power-loss protection. This is what NVMe Gen4 in a well-packed node feels like.
SATA SSDTens of thousands of IOPS and p99 in the low milliseconds. Perfectly adequate for most sites — and worth recognising on sight, because it is frequently sold as something else.
Network-attached volumeSingle-digit to low tens of thousands of IOPS, p99 latency in the several-millisecond range, and occasional spikes far worse than that. Sequential throughput may look excellent. The latency will not, and the latency is what your database waits on.
Throttled after a burstA run that opens at 60,000 IOPS and settles at 3,000 around the forty-second mark. Only a time-based run longer than the burst window will ever show you this, which is precisely why short benchmarks stay popular.

Add --status-interval=10 and watch the run instead of the summary. An average across sixty seconds hides a cliff; ten-second slices show it clearly. A disk that halves its throughput thirty seconds in is a disk with a credit system, and your nightly backup is going to find the bottom of it.

Memory: bandwidth, and what the capacity figure hides

Capacity is the spec that gets sold; bandwidth is the spec that gets felt. It is also where a badly packed node shows itself, because memory controllers are shared: a neighbour streaming through a large dataset costs you real bandwidth even when your steal time looks respectable.

  • sysbench memory --memory-block-size=1M --memory-total-size=64G --memory-oper=read run gives a rough transfer rate. It is a crude proxy, but it is available everywhere and comparable between runs on the same box, which is most of what you need.
  • mbw 1024 or a STREAM build gives a better figure if you can install one. On a modern server platform, copy and triad results belong in the tens of gigabytes per second.
  • Confirm the capacity is real: free -h should match the plan, and the si and so columns in vmstat 1 should sit at zero throughout a benchmark. A VPS that swaps under load has less usable memory than its plan page claims.
  • Check for a balloon driver with lsmod | grep balloon. Ballooning lets a hypervisor reclaim memory from a running guest. It is a legitimate technique, and it is also the reason your available RAM can shrink without anyone sending you an email about it.

Network: throughput, latency, and the route you were not shown

A gigabit port is a claim about a cable. What you are actually buying is a path — from your instance, through the provider's uplinks and whatever transit they bought, to the people who use your service. Measure the path, not the port.

  1. 1

    Throughput, in both directions

    iperf3 -c <server> -P 8 -t 30 measures egress; add -R to measure ingress. Use eight parallel streams, because a single TCP stream over a long path is bounded by the bandwidth-delay product rather than by your port and will under-report badly. Test against two or three different endpoints: a public iperf3 server is shared infrastructure too.

  2. 2

    Latency to the people who matter

    ping for the baseline round trip, then mtr -rwzbc 100 <target> against networks your users are genuinely on. mtr exposes per-hop loss and jitter, which is how you tell a saturated uplink from a merely long path. Twenty milliseconds of RTT is worth more to a web application than doubling the port speed.

  3. 3

    Sanity-check the port itself

    A gigabit port tops out near 118 MB/s once protocol overhead is accounted for. Anything reporting more on a 1 Gbps plan is measuring to a local cache. Reaching 10 Gbps takes parallel streams and tuned buffers; a single-stream test will never show it to you.

  4. 4

    Test at peak, not at dawn

    Uplink contention is a time-of-day phenomenon. A 2 a.m. result from a datacentre in Amsterdam tells you very little about how the same rack behaves at 9 p.m. local time, which is when your users arrive.

Skip consumer speed-test tools for this. They pick a nearby node and report the best of several short bursts — a design intended to flatter a home connection, and one that says almost nothing about a server's transit quality. Read /locations alongside these numbers: the region you choose changes the route before any amount of tuning does.

Unmetered and unlimited are different claims, and neither is measurable with iperf3. Read the terms: a plan can be genuinely unmetered on volume and still shaped above a threshold. The benchmark tells you the speed. Only the policy tells you for how long you keep it.

Put it in one script and keep the raw output

The value of a benchmark compounds only if you can repeat it. Write the whole sequence into a single shell script that stamps its results with the date, the hostname, the region and the tool versions, then keep that script somewhere you will find it again — the same repository as your provisioning code is the obvious place.

  • Run it on every new server within the first hour, before the box has a job. That is your baseline, and it is worth more to you than any published comparison ever will be.
  • Run it again whenever something feels slow. Slow is a feeling; a median that dropped forty percent against last quarter's run is an argument, and support queues respond to arguments.
  • Run it on a provider you are considering before you move anything to them. /guides has the full no-downtime migration sequence, and benchmarking the destination belongs at the start of that sequence rather than after the DNS has already moved.
  • Keep the raw output, not a tidy summary. Six months later the percentile distribution will tell you something the single average you wrote down cannot.

Aggregate scripts exist that run most of this in one command, and the well-known one is genuinely useful for a quick comparison between hosts. It is also a remote script piped into a root shell on a box you are about to trust with something. Read it first, or run it on a machine you are willing to throw away. The convenience is real; so is the habit it teaches.

What a benchmark cannot tell you

These numbers cover one axis. A server that wins every test above can still be the wrong server, and the properties that decide that are not measurable with fio.

  • Which law applies. The jurisdiction your data physically sits in decides who can compel its disclosure, and no benchmark has an opinion on the matter. /offshore-hosting covers what actually changes between countries, and it is usually more consequential than a twenty percent difference in IOPS.
  • What the provider logs, and for how long. A fast node that retains six months of connection records is a materially different product from a slower one that retains none.
  • What it took to buy. Whether an identity document and a card were required is a property of the purchase rather than the hardware — /no-kyc-vps and /pay-with describe the other model.
  • How it behaves during an incident. Time to a first human reply, whether a null route is announced or silent, whether a snapshot genuinely restores. You learn these by using a provider or by asking pointed questions before you do.
  • Whether today's number holds. A median is a measurement of today's neighbours. Re-run quarterly, because nodes get repacked and nobody sends a notice when yours does.

Benchmark before you commit, not after

The full sequence takes about twenty minutes and costs a few cents on hourly billing. That asymmetry is the whole argument for doing it: a rented hour is a far cheaper way to evaluate a host than a year of quietly tolerating one.

  1. 1

    Buy the smallest instance in the region you want

    Performance characteristics follow the node and the region far more than the plan size. A one-core instance in the same rack tells you most of what a larger one will do, for a fraction of the money, because the CPU model, the storage class and the network path are identical.

  2. 2

    Run the full sequence twice

    Once on arrival, once at the busiest local hour. Two honest runs on one instance is a much better signal than one run compared against five providers' marketing pages.

  3. 3

    Measure the things that are not speed

    Open a support ticket about something real and time the reply. Take a snapshot and restore it. Reboot from the panel and time that too. These are product measurements as much as IOPS is, and they are usually what decides whether you stay.

  4. 4

    Then size the plan you will actually run

    With a measured single-thread figure and a measured fsync latency in hand, sizing stops being guesswork. /guides has a sizing method that takes exactly those two numbers as its input.

systemd-detect-virt, lscpu, cpu.maxWhat you actually bought: full virtualization or a shared kernel, which physical CPU generation, and whether a quota is hiding behind the advertised core count.
sysbench cpu, one thread and N threadsThe sequential ceiling and the parallel ceiling. Keep the events per second for both, and keep the ratio between them — the ratio is the contention signal.
vmstat and mpstat under loadSteal percentage. Keep the figure measured during the all-core run, never the one measured at idle, and note if the hypervisor reports no steal at all.
fio randread, randwrite, fdatasyncIOPS and, far more usefully, p99 and fsync latency. Keep the percentiles and the ten-second slices, not the summary line.
sysbench memory, free, vmstat si/soMemory bandwidth, plus proof that nothing is swapping and nothing is being reclaimed underneath you.
iperf3 -P 8 both ways, mtrUsable throughput in each direction and per-hop loss to the networks your users are really on.

Frequently asked questions

How long should each benchmark run?

Sixty seconds as a minimum, using the tool's time-based mode so the duration is a duration rather than however long a fixed amount of work happens to take. Anything shorter measures a burst allowance instead of a server. For storage in particular, run long enough to exhaust any credit system: if throughput is still steady at ninety seconds, it is real.

What counts as a good steal time?

Under half a percent is healthy, up to roughly two percent is ordinary on a busy shared node, and anything sustained above ten percent means you are queueing for a core you believe you own. Measure it while the all-core CPU test is running — an idle guest always reports close to zero, which is why idle readings are so often quoted.

Is dd a valid disk benchmark?

Only as a smoke test. Without oflag=direct it measures the page cache rather than the disk, and a stream of zeros is nearly free on any storage that compresses or thin-provisions. Use fio with --direct=1 and read the latency percentiles; the headline throughput figure is the least informative part of the output.

Why is my single-core score lower than the advertised clock suggests?

Three usual causes. The physical CPU is an older generation than the plan page implies; the vCPU is an SMT sibling sharing execution units with another tenant; or a cgroup quota is capping you. lscpu answers the first, the all-core scaling ratio answers the second, and cat /sys/fs/cgroup/cpu.max answers the third.

Can I trust a provider's published benchmarks?

Treat them as an upper bound. They were run on an idle node, at a quiet hour, with the best of several attempts kept — which is not dishonest, but it is not your Tuesday afternoon either. The only number that describes your server is the one you measured yourself, on the plan you are paying for.

Do high IOPS matter for a small website?

Far less than people assume. A modest site is bounded by single-thread CPU and by commit latency, not by aggregate IOPS. If you optimise one storage number, optimise the fsync percentile — that is what a database transaction and a session write actually wait on.

Should I benchmark a GPU server the same way?

The method transfers; the tools do not. VRAM capacity, memory bandwidth and the precisions the card supports decide throughput far more than the host CPU does, and the measurement that counts is tokens or images per second on the model you intend to run. /gpu-server and the GPU comparison in /guides cover that side. The CPU, disk and network tests here are still worth running, because a fast card behind a slow disk spends its life waiting on the dataset.

Does benchmarking violate the acceptable use policy?

Reasonable benchmarking does not, at any provider worth using — you are measuring a resource you rented. What draws attention is duration: an hour of tests is diagnostics, a week of pegged cores on a shared node is a workload you did not declare. Run what you need, keep the output, and stop.

Uygulamaya geçirin.

$3.49/mo'dan başlayan bir offshore sunucu dağıtın · 8 kripto para birimi · KYC yok.