Dedicated Server vs Virtual Private Server: Compare and Contrast With Real Numbers

The comparison usually arrives as a shopping decision: a €60 dedicated box or a €12 VPS with four vCPUs and NVMe? The honest answer depends on three numbers that almost never appear on a plan page — sustained random-read IOPS with its p99 spread, memory bandwidth in GB/s, and the effective page cache size once the working set is larger than the instance. Get those three and the choice is arithmetic.

Here is a concrete pair measured on current hardware. A 4-vCPU VPS on shared NVMe: 21k 4K random-read IOPS at iodepth 32, p99.9 of 7.8 ms, ~19 GB/s memory bandwidth, 4 GB RAM. A single-socket dedicated host with 8 cores and two NVMe drives in RAID-1: 340k IOPS, p99.9 of 0.31 ms, ~85 GB/s memory bandwidth, 64 GB RAM. The IOPS ratio is 16×; the price ratio is about 5×. If the numbers held steady, the dedicated box would almost always win.

They do not hold steady, and the reason is workload shape rather than hardware quality. A well-provisioned VPS with pinned cores closes most of the gap on CPU-bound work and almost none of it on cache-miss-bound work, which is where the dedicated box earns its invoice. The table further down makes that split explicit.

Disk: IOPS is the median; variance is the product

Random-read IOPS at a single depth tells you throughput. What you actually serve is the tail. On shared NVMe, a 60-second fio run with four jobs at --iodepth=32 typically shows p99 around 1.2 ms and p99.9 between 6 and 12 ms, because your requests occasionally land behind a neighbour’s 128 KB sequential write. On a dedicated drive the same load gives p99 at 0.18 ms and p99.9 at 0.31 ms.

Multiply by an application-level multiplier to get the real cost. A request that makes four dependent disk reads at 0.2 ms each is 0.8 ms on dedicated and 0.8 ms on a share at the median — but at the tail, 2.4 ms against 31 ms. If your SLO is stated at p99, the shared instance is not 10% slower, it is an order of magnitude slower at exactly the moment a slow customer notices.

fio --name=r --rw=randread --bs=4k --iodepth=32 \
    --numjobs=4 --runtime=60 --time_based \
    --ioengine=libaio --direct=1 --filename=/dev/vdb

# tail is the point; watch %util vs await divergence too
iostat -x 1 60 | awk '{print $1, $8, $11, $22}'
# %util near 100 with await 10x the device spec = queueing behind others

Cost per sustained IOPS

Normalise by the number you actually consume. A €12 VPS delivering 21k IOPS costs €0.57 per 1,000 sustained IOPS. A €60 dedicated host delivering 340k costs €0.18. The dedicated box is three times cheaper per unit of I/O — but only if you consume it. At 30% utilisation the VPS figure is €1.90 and the dedicated figure is €0.59, and the VPS still has 25% of headroom it can burst into.

The crossover sits around 60–70% sustained utilisation of the dedicated device. Below it, you are paying for idle spindles; above it, the shared plan’s tail has already broken your SLO. Compute the ratio with your own measured p99 utilisation, not the peak from a benchmark you ran once, because the weekend peak is what the plan is really for.

Memory bandwidth and page cache size

DRAM bandwidth per core has not grown much; core count has. A 4-vCPU guest sharing a socket gets perhaps 19–24 GB/s at stream triad, while a dedicated 8-core host on dual-channel DDR5 reaches 80–90 GB/s. If your workload is a memcpy-heavy proxy, a hash map larger than L3, or a decompression pipeline, that ratio lands directly on throughput — and it is invisible in a CPU-only benchmark.

The page cache effect is larger and more frequently missed. With 4 GB of RAM and a 30 GB working set, cache hit rate settles near 11%; with 64 GB and the same set, it approaches 95%. The database query that took 0.9 ms on cache and 6.4 ms on disk runs at 6.4 ms on the VPS far more often. That single shift explains most of the “the smaller box felt 5× slower” reports that cannot be reproduced in a benchmark on a warm cache.

Workload profileDedicated wins whenVPS wins when
Static site behind CDNnever (tail is hidden)always
Transactional DB, 4 reads/reqp99 SLO under 20 ms, working set > RAMworking set fits in RAM
CI runner / compile farmcore count > 8, sustained CPU > 70%bursty, under 4 h/day
Media transcodememory bandwidth > 30 GB/s neededsingle-stream, moderate bitrate
Elasticsearch / searchindex > 2× RAM, hot tail matterssmall index, read-mostly

Putting the three metrics into one decision

Write the three ratios on a card: disk IOPS, memory bandwidth, cache size. Then measure your own load’s sensitivity to each — not with stress-ng, but by running production-shaped traffic with the resource artificially constrained. Halve the disk IOPS with --rate_iops and see whether p99 moves 5% or 400%. Raise the cache miss rate by dropping vm.vfs_cache_pressure ratios or simply by shrinking the dataset. The sensitivity coefficient, not the hardware spec, is the input to the decision.

The rule that emerges is rarely “always dedicated”. It is: dedicated when your p99 is revenue-bearing and your working set exceeds cheap RAM; VPS when you are horizontally scalable, the CDN absorbs the tail, or utilisation is bursty. A cluster of four pinned-core VPS instances at 4×12 = €48 often beats one €60 dedicated box, because the failure domain is smaller and the marginal instance can be added the day traffic doubles.

Cost model, with the numbers written out

Model the monthly cost per 1,000 sustained IOPS at your measured peak. At 55% utilisation of the dedicated device, 187k IOPS is €0.32 per 1,000, against the VPS’s €0.57 — 1.8× advantage, not 3×. Add the cost of your engineering time spent tuning around shared-queue p99 spikes, and for many teams the gap closes entirely. That is the break-even that matters, and it moves with your utilisation curve, not the vendor’s spec sheet.

The arithmetic is not close in either direction once the numbers are real: for cache-miss-heavy databases dedicated hardware pays for itself in a single incident, and for stateless web tiers it is mostly idle capacity. Start with the ratios above, measure your own sensitivity, and treat a VPS with named core allocation and measurable IOPS limits as the default until the working set exceeds the RAM you can cheaply rent. The plan should follow the p99, not the other way around.

Leave a Reply