Skip to content
Back to Blog
Linux & Server11 min read

Best Cheap VPS Under $10/Month: 8 Advanced Tweaks

You've already chosen a budget VPS. Now harden the kernel, tune I/O schedulers, and squeeze every drop of performance from limited RAM and CPU—without spending more.

Written by Abdul AbrorTechnical Hosting Support Engineer
Best Cheap VPS Under $10/Month: 8 Advanced Tweaks
On this page

Stop configuring like it's 2015

You've picked a VPS under ten dollars. Now comes the real work.

Most tutorials stop at SSH keys and a firewall. That's fine for a side project, but if you're running production traffic or multiple sites on 1 GB of RAM, you need to think in kilobytes and system calls. The difference between a sluggish server and a responsive one often lives in /proc/sys, swap tuning, and which processes you allow to fork.

This guide assumes you already know how to lock down SSH and run apt update. We're going straight to the kernel, the scheduler, and the edge cases that separate a hobbyist setup from something that survives a traffic spike.

Move 1: Tune the kernel's memory overcommit behavior

By default, the Linux kernel is optimistic. It promises memory to every process that asks, even if physical RAM plus swap can't cover the total.

That's great until the OOM killer wakes up and shoots a random process—often your database or web server. On a budget VPS with 1–2 GB of RAM, you can't afford that lottery.

Check your current setting:

cat /proc/sys/vm/overcommit_memory

A value of 0 means heuristic overcommit (the default). Change it to 2 for strict accounting:

echo 2 > /proc/sys/vm/overcommit_memory
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf

Now the kernel refuses allocations that exceed RAM plus swap. Some badly written software might complain, but your critical services won't vanish mid-request. Pair this with a reasonable overcommit_ratio (default 50 means 50% of RAM can be overcommitted):

echo "vm.overcommit_ratio=80" >> /etc/sysctl.conf
sysctl -p

I've seen support tickets where a WordPress site froze during a plugin update because PHP tried to allocate more memory than existed. Strict accounting would have returned an error instead of hanging the process.

Move 2: Switch to the mq-deadline I/O scheduler for SSDs

Most cheap VPS providers use SSD storage now. The old CFQ (Completely Fair Queuing) scheduler was designed for spinning disks.

Check your current scheduler:

cat /sys/block/vda/queue/scheduler

(Replace vda with your actual block device—use lsblk to find it.)

If you see [mq-deadline] or [none], you're fine. If it's [cfq] or [deadline], switch:

echo mq-deadline > /sys/block/vda/queue/scheduler

Make it persistent by adding a udev rule in /etc/udev/rules.d/60-scheduler.rules:

ACTION=="add|change", KERNEL=="vda", ATTR{queue/scheduler}="mq-deadline"

For NVMe drives (nvme0n1), none is often the best choice since NVMe has deep hardware queues. Test with fio if you want to measure the difference, but in practice the switch cuts tail latency on database writes by 10–20%.

Move 3: Enable and tune zswap for extra headroom

zswap compresses pages before they hit disk swap. On a VPS with 1 GB of RAM, this can double your effective memory at the cost of a few CPU cycles.

Check if it's already enabled:

cat /sys/module/zswap/parameters/enabled

If it says N, enable it at boot by editing /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="quiet zswap.enabled=1 zswap.compressor=lz4 zswap.max_pool_percent=25"

Then run:

update-grub
reboot

The lz4 compressor is faster than the default lzo. Setting max_pool_percent=25 means zswap can use up to 25% of total RAM for the compressed pool. Tune that number based on your workload—higher if you run memory-hungry apps, lower if CPU is already pegged.

After reboot, verify:

grep -r . /sys/module/zswap/parameters/

You should see enabled:Y and compressor:lz4. In support tickets I handled, enabling zswap kept a Magento 2 site alive on 2 GB where it used to crash during catalog reindexing.

Move 4: Disable transparent huge pages for databases

Transparent Huge Pages (THP) sound great: the kernel automatically promotes 4 KB pages to 2 MB pages for better TLB efficiency. In reality, they cause latency spikes and memory bloat for databases like MySQL, PostgreSQL, MongoDB, and Redis.

Check the current state:

cat /sys/kernel/mm/transparent_hugepage/enabled

If you see [always], disable it:

echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

Make it permanent by adding this to /etc/rc.local (create it if missing and make it executable):

#!/bin/bash
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
exit 0

Or use a systemd service if your distro doesn't use rc.local anymore. Redis documentation explicitly warns against THP. The symptom is random 99th-percentile latency spikes that don't correlate with query load.

Move 5: Lower vm.swappiness and raise vm.vfs_cache_pressure

The default swappiness=60 means the kernel starts swapping out anonymous pages fairly aggressively. On a VPS where disk I/O is shared and slower than local NVMe, you want to prefer keeping active processes in RAM.

Set it to 10:

echo "vm.swappiness=10" >> /etc/sysctl.conf
sysctl -p

This tells the kernel to avoid swapping until memory pressure is high.

At the same time, raise vfs_cache_pressure from 100 to 150 or 200:

echo "vm.vfs_cache_pressure=150" >> /etc/sysctl.conf
sysctl -p

This makes the kernel more willing to reclaim dentries and inodes (filesystem metadata cache) instead of application memory. For a web server serving mostly dynamic content, you'd rather cache database rows than directory entries.

The combined effect: your app stays in RAM longer, and the kernel drops less-useful caches first.

So what if you're running multiple sites on one VPS?

Resource limits per user or per application become critical. cgroups v2 is the modern answer, but for a quick fix, use systemd service units with MemoryMax and CPUQuota.

Create a drop-in for your web server:

systemctl edit nginx

Add:

[Service]
MemoryMax=400M
CPUQuota=80%

This caps nginx at 400 MB and 80% of one CPU core. If a plugin or script goes rogue, it won't starve your database or SSH daemon. Repeat for PHP-FPM, MySQL, Redis, whatever else you run.

You can stack limits. A typical budget VPS might allocate:

  • Web server: 30% CPU, 400 MB RAM
  • Database: 40% CPU, 500 MB RAM
  • PHP workers: 20% CPU, 300 MB RAM
  • System + SSH: 10% CPU, 100 MB RAM

Leave some headroom. The numbers depend on your traffic and queries, but the principle is the same: explicit limits prevent one service from monopolizing the box.

Move 6: Compile and load a minimal custom kernel (optional, high effort)

Stock distro kernels include drivers for hardware you'll never see on a VPS: sound cards, TV tuners, exotic RAID controllers. Stripping that cruft saves RAM and reduces attack surface.

This is a weekend project, not a five-minute fix. But if you're serious about squeezing performance, a minimal kernel can free 50–100 MB of RAM on boot.

Start with your distro's kernel config as a base:

cp /boot/config-$(uname -r) .config
make menuconfig

Disable:

  • All wireless drivers
  • Sound subsystem
  • Amateur radio, IrDA, NFC
  • USB gadgets, media drivers
  • Filesystems you don't use (NTFS, HFS, etc.)
  • Any hardware crypto or RAID you don't have

Enable only virtio drivers (virtio-net, virtio-blk, virtio-scsi) since most VPS hypervisors use them. Compile with:

make -j$(nproc) deb-pkg

Install the resulting .deb files and reboot. Verify boot, then remove the old kernel.

Is it worth it? Depends. If you're already at 90% RAM usage, yes. If you have headroom, spend your time elsewhere.

Move 7: Harden sysctl network parameters against SYN floods

Budget VPS hosts rarely offer DDoS protection. A small SYN flood can fill your connection tracking table and lock you out.

Add these to /etc/sysctl.conf:

net.ipv4.tcp_syncookies=1
net.ipv4.tcp_max_syn_backlog=2048
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_syn_retries=2
net.netfilter.nf_conntrack_max=65536

Then apply:

sysctl -p

tcp_syncookies allows the kernel to handle SYN floods without allocating full connection state. The backlog and retry tuning keeps half-open connections from piling up. Raising nf_conntrack_max prevents the conntrack table from overflowing if you use iptables with connection tracking (most firewalls do).

If your VPS is already under attack, these won't save you—you need upstream filtering. But they buy time and prevent casual port scans from degrading performance.

Move 8: Audit and disable unnecessary systemd services

A fresh VPS image often runs services you'll never use. Each one consumes RAM and CPU, even if idle.

List all enabled services:

systemctl list-unit-files --state=enabled

Common candidates to disable:

  • ModemManager (unless you're using a 3G modem on your VPS—you're not)
  • bluetooth.service
  • avahi-daemon.service (Bonjour/Zeroconf)
  • cups and cups-browsed (printing)
  • iscsid (iSCSI initiator)

Disable with:

systemctl disable --now avahi-daemon.service

Be careful with systemd-resolved and systemd-networkd. Some distros need them for DNS and networking. Check your setup first.

After trimming, reboot and run:

systemctl list-units --type=service --state=running

You should see only SSH, your web server, database, and a handful of system services. I've freed 50 MB of RAM on Ubuntu VPS images just by killing printer and modem daemons.

Watch for CPU steal time, not just load average

On a shared VPS, top might show low CPU usage while your app feels sluggish. That's because the hypervisor is stealing cycles to give to other tenants.

Check steal time:

top

Look at the %st column. Anything above 5% consistently is bad. Above 15% is unusable. If you see high steal, your provider is overselling. No kernel tuning will fix that—you need to complain or migrate.

You can also check with:

sar -u 5 12

The %steal column shows the same metric over time. Document it before opening a support ticket so you have evidence.

What to measure before and after

Don't tune blindly. Establish a baseline first.

Run a load test with ab or wrk against your app. Record:

  • Average response time
  • 95th and 99th percentile latency
  • Requests per second
  • Memory usage (free -m)
  • CPU usage and steal time (sar -u)

Apply the moves above one at a time. Reboot if needed, then re-run the test. Some changes (like zswap and swappiness) show up under sustained load, not idle conditions. Others (like disabling THP) eliminate tail latency spikes that only appear in the 99th percentile.

If a change makes things worse, roll it back. Not every tuning fits every workload. The goal is a server that stays responsive under your specific traffic and application mix, not a checklist to blindly copy.

FAQ

How much swap should I allocate on a cheap VPS?

Start with RAM size if you have room on disk. For a 1 GB VPS, create a 1 GB swap file. With zswap enabled, you'll rarely hit disk swap anyway. Anything beyond 2x RAM is wasted space unless you're hibernating the machine (you're not).

Will these tweaks void my provider's TOS?

No. You're tuning the kernel and disabling services, not attacking other tenants or bypassing resource limits. Managed hosting might discourage custom kernels, but unmanaged VPS hosting expects you to do this.

Can I use these settings on a container (LXC, Docker)?

Partially. Containers share the host kernel, so you can't change sysctl parameters that affect the whole system. zswap and I/O schedulers are host-level. You can set cgroup limits and disable services inside the container. If you control the host, tune there. If you're a tenant, work with what the provider allows.

Should I enable zram instead of zswap?

zram creates a compressed block device in RAM and uses it as swap. It's simpler than zswap and often performs better on very low-memory systems (512 MB or less). For 1 GB and up, zswap integrates better with traditional swap and gives you more control. Try both and benchmark with your workload.