Swap File or More RAM? Diagnosing a VPS That Is Quietly Out of Memory

A 2 GB VPS with a 2 GB swap file will appear healthy for months. Uptime is fine, monitoring shows no crashes, and the site loads — yet every page takes 300–900 ms longer than it should. That pattern is a memory shortage being absorbed by swap rather than reported as an incident. The table below separates normal swap use from the kind that means you are under-provisioned.

Swap usedSwap I/O rateInterpretationAction
0–5%0HealthyNone
5–25%0Cold pages parked, never touchedWatch only
5–25%Sustained >100 KB/sWorking set exceeds RAMFind the consumer, then size up
>50%AnyActive thrashingUpgrade RAM this week
100%HighOOM kills imminentUpgrade now

The distinction that matters is used versus actively moving. Swap pages that were written once and never read again cost nothing. Swap pages being read back under load cost disk latency on every request — typically 0.1–1 ms on NVMe and far worse on network-attached storage.

Measure Swap Activity, Not Swap Usage

# 1. How much is used at all
free -m | awk 'NR==3{printf "swap used: %s MB of %s MB\n", $3, $2}'

# 2. Is it actually moving? (run under real load)
vmstat 5 12 | awk 'NR>2{print "si:",$7" so:",$8" KB/s"}'

# 3. Which processes were swapped out
for pid in $(ls /proc | grep -E '^[0-9]+$'); do
  awk '/VmSwap/{if($2>1000) print $2" kB", "PID "'$pid'}' /proc/$pid/status 2>/dev/null
done | sort -rn | head -10

# 4. Per-device swap I/O
sar -W 1 5 2>/dev/null || cat /proc/vmstat | grep -E 'pswp(in|out)'

Step 3 is the one most people skip. It tells you which process is being pushed out. If PHP-FPM workers dominate the list, the pool is too large. If MySQL dominates, the buffer pool is competing with the OS. If a single app worker dominates and grows over days, you have a leak that no RAM tier will fix permanently.

Distinguish Swap Latency From Server Latency

Confirm swap is the actual culprit before buying anything:

  • Compare TTFB cold versus warm. If the first request after a quiet period is 2–5× slower than later ones, pages are being faulted back from swap. The measurement method is covered in our latency and TTFB analysis guide.
  • Check disk read latency during traffic. Swap-ins show up as elevated await on the swap device in iostat -x.
  • Look at application-level p99. Swap affects tail latency first. A p99 that drifts while p50 stays flat is the classic signature.

Three Temporary Fixes, Ranked

1. Reduce the working set (best). Cut PHP-FPM pm.max_children, lower innodb_buffer_pool_size, cap journald, prune Docker images. This buys real headroom without changing the bill.

# PHP-FPM: size the pool to measured concurrency, not to RAM/40
pm = dynamic
pm.max_children = 8      # ~8 x 50 MB = 400 MB
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4

# MySQL: leave room for the OS and web tier
[mysqld]
innodb_buffer_pool_size = 512M

2. Tune swappiness down (temporary). Setting vm.swappiness=10 makes the kernel prefer dropping page cache over swapping application memory. It reduces churn but does not create capacity — it only delays the symptom.

3. Move swap to faster storage or add zram (temporary). Compressed RAM swap (zram) can absorb 200–400 MB of cold pages using far less physical memory than plain swap, and it is much faster than disk. It is a genuine stopgap for a small VPS, though it still consumes the RAM it is trying to save.

Sizing Swap Correctly First

Before diagnosing, confirm the swap file itself is not the problem. A common misconfiguration is a swap file created with the wrong permissions or on a filesystem that does not support it well, which produces slow swap even at low utilization.

Installed RAMRecommended swapSwappinesszram worth it?
512 MB1 GB60Yes, 256 MB
1 GB1–2 GB30–60Yes, 512 MB
2 GB2 GB10–30Optional
4 GB+2–4 GB10No
# Verify the swap file is correct
swapon --show
ls -l /swapfile        # expect -rw------- root root, mode 600
filefrag -v /swapfile | head -3   # check for fragmentation

# Fixed-size swapfile, no fragmentation
sudo swapoff /swapfile
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

The highest swappiness values belong on the smallest servers, because at 512 MB the alternative to swapping is an OOM kill. On a 4 GB server, swap is a crash cushion and nothing more, so swappiness of 10 keeps the kernel from parking live pages there.

When to Stop Tuning and Change the Tier

  • Sustained swap throughput above 100 KB/s after reducing the working set
  • Available memory below 10% during normal (not peak) hours
  • p99 latency more than 3× p50 with no application change
  • Any OOM kill in the journal, regardless of frequency

Two or more of those means the tier is wrong. One means a specific process needs fixing. Our plan comparison with per-tier pricing makes the arithmetic explicit: if the next RAM tier costs $3/month and a swap-driven latency regression costs you conversions, the upgrade is the cheaper option on almost any metric.

Swap is a cushion, not a substitute for capacity. Keep it configured — a VPS with no swap dies harder when it hits the wall — but never let it absorb a shortage that a $3 tier change would remove. InterServer’s flat renewal pricing keeps that upgrade cost predictable year over year: check InterServer’s VPS tiers. For a workload with seasonal peaks, Vultr’s hourly resizing lets you run a bigger tier through the busy month and drop back afterwards.

Affordable-Vps-Server-Author
Affordable-Vps-Server-Author
Articles: 290

Leave a Reply