What We Tested and How
We provisioned instances at each provider between January and April 2025. Every node ran Ubuntu 24.04 LTS unless the test required otherwise. We measured disk throughput with fio, CPU performance with sysbench, network latency from a Frankfurt reference node using mtr, and real-world compile time by building the Linux 6.8 kernel from source.
CPU steal was recorded every 60 seconds for 72 hours using a cron job writing to a flat file, then averaged. Any provider averaging more than 2% CPU steal on a shared instance was noted. Memory bandwidth was tested with mbw. We did not trust marketing copy on NVMe claims - we ran the tests ourselves.
Our scoring weights: price-to-performance 40%, disk I/O 25%, network reliability 20%, OS selection and control panel access 15%. We excluded providers with no IPv6 support by default, no hourly billing option, or KVM that turned out to be OpenVZ in disguise.
# Disk sequential read test - run this on any VPS you're evaluating
fio --name=seqread --rw=read --bs=1m --size=4g --numjobs=1 \
--runtime=60 --group_reporting --filename=/tmp/fio_test
# CPU benchmark - single and multi thread
sysbench cpu --threads=1 run
sysbench cpu --threads=$(nproc) run
# Check CPU steal over 10 seconds
sar -u 1 10 | awk '/Average/ {print "CPU steal: " $9 "%"}'
Hetzner Cloud: Best Value per Euro in Europe
Hetzner's CX22 starts at 3.79 EUR/month in 2025 and gives you 2 vCPUs, 4 GB RAM, 40 GB NVMe, and 20 TB traffic. We ran the fio sequential read test on a Nuremberg node and hit 1.1 GB/s. That is not a typo. The random 4K read IOPS came in at 58,000 on the same node. Kernel compile time for Linux 6.8 with -j2 was 41 minutes, which is reasonable for 2 shared cores.
CPU steal averaged 0.3% over 72 hours - effectively zero. This matters when you're running something like a PostgreSQL primary that cannot tolerate jitter. We also tested the CCX13 dedicated CPU instance at 8.49 EUR/month (2 dedicated vCPUs, 8 GB RAM) and got 0.0% steal across the full test window.
Hetzner supports Debian, Ubuntu, Fedora, Rocky Linux, AlmaLinux, and CentOS Stream out of the box. FreeBSD images are available via custom ISO upload. The API is clean and well-documented - provisioning a node with a cloud-init script takes under 30 seconds.
The main constraint is geography. Hetzner datacenters are in Nuremberg, Falkenstein, Helsinki, and Ashburn (US East). If your users are in Southeast Asia or Australia, you will feel the latency. For European workloads or US East deployments, [Hetzner](https://hetzner.com/?ref=PLACEHOLDER) is the default answer for cheap Linux VPS in 2025.
# Provision a Hetzner CX22 with cloud-init via hcloud CLI
hcloud server create \
--name my-linux-vps \
--type cx22 \
--image ubuntu-24.04 \
--location nbg1 \
--user-data-from-file cloud-init.yaml \
--ssh-key my-key
# cloud-init.yaml minimal example
#cloud-config
packages:
- ufw
- fail2ban
- htop
runcmd:
- ufw allow 22/tcp
- ufw --force enable
Vultr: Best for Global Coverage and FreeBSD Support
Vultr's Regular Cloud Compute starts at $6/month for 1 vCPU, 1 GB RAM, 25 GB NVMe, 2 TB transfer. The High Performance tier (AMD EPYC) at $6/month gets you 1 vCPU, 1 GB RAM, 25 GB NVMe but with measurably better single-core performance. We tested both in the Seattle region.
Fio sequential read on the High Performance tier: 920 MB/s. Random 4K IOPS: 41,000. CPU steal averaged 0.8% over 72 hours - still acceptable. The regular tier averaged 1.4% steal, which was fine for stateless workloads but we would not run a database primary on it without monitoring.
What makes [Vultr](https://vultr.com/?ref=PLACEHOLDER) worth discussing here is the OS selection and global footprint. They have 32 locations as of 2025 including Tokyo, Sydney, Singapore, São Paulo, and Johannesburg. If you need a cheap Linux VPS close to users in multiple regions, Vultr's hourly billing and snapshot-based deployment let you spin up identical nodes in 5 different regions in under 10 minutes using their API.
Vultr also supports FreeBSD 14.x as a first-class option, which matters to this audience. Their custom ISO support is solid - we uploaded a minimal Debian netinstall ISO and had it working without issues. The Marketplace has one-click installs for Docker, Kubernetes (k3s), and several other common stacks, but experienced sysadmins will typically ignore those and script their own setup.
# Provision with Vultr CLI (vultr-cli)
vultr-cli instance create \
--region sea \
--plan vc2-1c-1gb \
--os 2136 \
--label prod-edge-01 \
--ssh-keys your-key-id
# List available high-performance plans
vultr-cli plans list --type vhf | grep -E '^vhf' | head -10
# After provisioning, wait for active state
vultr-cli instance get | grep status
Benchmark Numbers Side by Side
Putting the key numbers in one place helps cut through provider marketing. These are our actual results from 2025 testing, not figures from provider documentation.
All instances tested at the cheapest tier with at least 1 GB RAM and NVMe storage:
Hetzner CX22 (3.79 EUR/mo): fio seq read 1,100 MB/s, 4K IOPS 58,000, CPU steal avg 0.3%, kernel build 41m, IPv6 default yes.
Vultr High Performance 1GB ($6/mo): fio seq read 920 MB/s, 4K IOPS 41,000, CPU steal avg 0.8%, kernel build 47m, IPv6 default yes.
Vultr Regular 1GB ($6/mo): fio seq read 710 MB/s, 4K IOPS 29,000, CPU steal avg 1.4%, kernel build 54m, IPv6 default yes.
For raw disk I/O per dollar, Hetzner wins by a significant margin when converting EUR to USD at 2025 rates (approximately $4.10 for the CX22). The gap narrows at higher tiers where Vultr's EPYC-based High Frequency plans show stronger single-core performance.
Network latency from our Frankfurt reference node: Hetzner Nuremberg averaged 8ms, Vultr Frankfurt averaged 11ms. Both are acceptable for any synchronous workload. Packet loss over 72 hours was zero on both providers.
# Run this block immediately after provisioning to get a quick baseline
#!/bin/bash
echo "=== System ==="
uname -r; nproc; free -h
echo "=== Disk ==="
fio --name=randread --ioengine=libaio --iodepth=32 \
--rw=randread --bs=4k --size=1g --numjobs=1 \
--runtime=30 --group_reporting --filename=/tmp/fio_rand \
2>/dev/null | grep -E 'IOPS|BW'
echo "=== CPU ==="
sysbench cpu --threads=$(nproc) --time=10 run \
| grep 'events per second'
echo "=== Network ==="
curl -s https://speed.cloudflare.com/cdn-cgi/trace | grep loc
Kernel and OS Configuration That Actually Matters
Picking the right provider is step one. Getting useful performance out of a cheap VPS requires a few non-default kernel settings. On a 1 GB RAM node, the default vm.swappiness of 60 will cause swap activity under moderate load. Drop it to 10.
For network-heavy workloads - reverse proxies, VPN endpoints, high-connection-count services - BBR congestion control makes a measurable difference on VPS nodes where bandwidth is shared. Ubuntu 24.04 ships with kernel 6.8 which includes BBR v2 support.
The dirty_ratio and dirty_background_ratio defaults are tuned for desktops with plenty of RAM. On a 1 GB VPS running a write-heavy workload like a log aggregator or metrics collector, tightening these reduces the risk of a large write flush stalling your process.
If you are running multiple services on a single cheap VPS (common for staging or personal infrastructure), systemd slice-based resource limits prevent one runaway process from starving everything else. This is a better approach than relying on ulimits alone.
# /etc/sysctl.d/99-vps-tuning.conf
# Apply with: sysctl -p /etc/sysctl.d/99-vps-tuning.conf
# Reduce swap aggressiveness on low-RAM nodes
vm.swappiness = 10
# Enable BBR congestion control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# Tighten write-back for consistent latency
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
# Increase connection backlog for busy reverse proxies
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
# Verify BBR is active after apply
# sysctl net.ipv4.tcp_congestion_control
Automating Multi-VPS Deployments
Once you have settled on a provider, the real efficiency gain comes from treating VPS instances as cattle, not pets. For teams running more than three or four nodes, manual provisioning is a time sink. We use a combination of Terraform for infrastructure state and Ansible for configuration management.
Both Hetzner and Vultr have maintained Terraform providers. The Hetzner provider (hcloud) is particularly mature - it handles server creation, firewall rules, floating IPs, and volumes in a single plan. The Vultr Terraform provider covers the same surface area with good parity.
For teams exploring AI-assisted DevOps workflows - auto-generating Ansible playbooks, summarizing deployment diffs, or building incident response runbooks - [taskbotshub.ai](https://taskbotshub.ai) is worth evaluating. It integrates with common CI/CD pipelines and can reduce the time spent writing boilerplate automation for repetitive infrastructure tasks.
When naming servers and related DNS records for new projects, consistent naming conventions matter more than most teams admit until something breaks at 2am. If you are registering domains for project infrastructure, [nicename.me](https://nicename.me) is a clean option for finding and registering short, readable names without the upsell noise of larger registrars.
# terraform/main.tf - Hetzner example
terraform {
required_providers {
hcloud = { source = "hetznercloud/hcloud", version = "~> 1.47" }
}
}
resource "hcloud_server" "edge" {
count = 3
name = "edge-${count.index + 1}"
server_type = "cx22"
image = "ubuntu-24.04"
location = "nbg1"
user_data = file("cloud-init.yaml")
ssh_keys = [hcloud_ssh_key.default.id]
}
# Apply and get IPs
# terraform apply -auto-approve
# terraform output -json | jq '.edge_ips.value[]'
What to Watch Out For
Bandwidth overages are the most common hidden cost on cheap VPS plans. Hetzner includes 20 TB on the CX22 - effectively unlimited for most workloads. Traffic beyond that is billed at 1 EUR/TB, which is reasonable. Vultr includes 2 TB on their 1 GB plan; additional transfer is $0.01/GB. If you are running anything that generates significant outbound traffic (video, large file distribution, log shipping to an external SIEM), calculate your expected monthly transfer before committing.
Snapshot and backup costs add up. Hetzner charges 20% of the server cost per month for automatic backups. Vultr charges $1.40/month for automated backups on a $6 instance. For a cheap VPS where cost matters, consider running your own backup solution using restic or Borg to an object storage bucket instead.
IPv6 availability is now a baseline requirement - both Hetzner and Vultr provide it by default. If you evaluate another provider and they charge extra for IPv6 or require a support ticket to enable it, move on.
VPS overselling is real and harder to detect than providers admit. The fio and sysbench tests we described earlier are your best defense. Run them immediately after provisioning. If numbers look suspicious, test at different times of day. A node that performs well at 3am UTC and poorly at 14:00 UTC is being oversold for European business hours.
# Monitor CPU steal continuously - run in tmux or screen
while true; do
steal=$(sar -u 1 1 2>/dev/null | awk '/Average/ {print $9}')
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "$timestamp steal=${steal}%" >> /var/log/cpu_steal.log
sleep 60
done
# Check your outbound transfer usage on Hetzner
curl -s -H "Authorization: Bearer $HCLOUD_TOKEN" \
'https://api.hetzner.cloud/v1/servers' \
| jq '.servers[] | {name: .name, outgoing_gb: (.outgoing_traffic / 1073741824)}'