Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Add a Swap File and Optimize Memory on a Small VPS

By Kokil Thapa | Last reviewed: September 2026

A 1 GB or 2 GB VPS is enough to run a Laravel app, WordPress site, or small API. Until traffic spikes, a cron job fires, or Composer runs during deploy. Then the kernel kills your database or PHP-FPM workers with an out-of-memory (OOM) error. The fix is not always a bigger plan. You need to add a swap file and optimize memory on a small VPS so the server has breathing room and each service stays within sane limits. I run several production sites on shared EC2 boxes with Linux system administration workflows, and swap plus tuning is the first thing I check when a client reports random 502 errors.

When should you add a swap file on a small VPS?

Swap is disk space the Linux kernel uses as overflow when physical RAM fills up. It is slower than RAM. On a web server it is a safety net, not extra performance.

Add swap when your VPS has 4 GB of RAM or less and runs more than one service. A typical stack—Nginx or Apache, PHP-FPM 8.3+, MySQL 8.4 or 9.7, Redis 8.10, and a queue worker—can exceed 1.5 GB during a deploy or backup. Without swap, the OOM killer picks a process and terminates it. That often means MySQL or your heaviest PHP worker.

Signs you need swap now:

  • dmesg or journalctl -k shows "Out of memory: Kill process"
  • MySQL restarts without a clear error in its error log
  • PHP-FPM logs show workers killed or "server reached max_children"
  • free -h shows available memory near zero during normal traffic

Skip swap only on ephemeral build containers or when you have guaranteed headroom and strict latency requirements. For a small VPS hosting a business site in Nepal, swap is cheap insurance—often Rs 0 on the same disk you already pay for.

Small VPS Memory LayoutPhysical RAM1–4 GB typicalFast — use firstSwap File1–2 GB on diskSlow — safety netPHP-FPMMySQLRedisNginxNo swap = OOM killer may drop MySQL or PHPSwap absorbs spikes during deploys and cron jobs
Add a swap file and optimize memory on a small VPS: RAM holds active workloads; swap catches spikes before the OOM killer strikes.

How do you create a swap file on Ubuntu step by step?

These steps work on Ubuntu 22.04 and 24.04—the versions I use on production servers. Adjust the size based on your RAM.

Choose swap size

Use this rule of thumb for web servers:

  • 1 GB RAM → 1 GB swap
  • 2 GB RAM → 1–2 GB swap
  • 4 GB RAM → 1 GB swap (tuning matters more than size)

Do not allocate 4 GB swap on a 20 GB disk. You will run out of space for logs and backups. Check free disk with df -h first.

Create and enable the swap file

  1. Verify current swap: sudo swapon --show
  2. Create a 1 GB file (change 1G if needed):
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

If fallocate fails on your provider's filesystem, use dd instead:

sudo dd if=/dev/zero of=/swapfile bs=1M count=1024 status=progress

Make it persistent across reboots:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Confirm:

free -h
sudo swapon --show

Secure the fstab entry

Wrong fstab syntax can boot your VPS into emergency mode. After editing, run sudo mount -a to test. Keep a provider console open during first reboot.

For a full server baseline, pair this with the Laravel on Ubuntu VPS with Nginx guide or the Symfony deployment walkthrough.

Swap File Setup FlowCheck diskfallocatechmod 600mkswapswapon/etc/fstabfree -hmount -aReboot testOfficial reference: Ubuntu swap documentationAlways verify with free -h before closing SSH
Ubuntu swap file creation: allocate, secure permissions, format, enable, persist in fstab, then verify after reboot.

What swappiness value should a web server use?

vm.swappiness controls how aggressively the kernel moves idle pages to swap. Default on Ubuntu is 60. That is too high for a database-backed web app.

Set swappiness between 10 and 20 for VPS web servers. RAM stays preferred. Swap activates mainly under pressure.

sudo sysctl vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl -p /etc/sysctl.d/99-swappiness.conf

Also consider vm.vfs_cache_pressure. A value of 50–100 reduces inode cache retention when memory is tight:

echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.d/99-swappiness.conf

The kernel documentation explains these knobs in detail. Read the official Linux kernel VM sysctl guide before tuning production values.

SettingDefaultWeb VPS recommendationWhy
vm.swappiness6010–20Keeps hot PHP and MySQL pages in RAM
vm.vfs_cache_pressure10050–100Reclaims filesystem cache under pressure
Swap size (1 GB RAM)none1 GBCovers deploy and backup spikes
Swap size (4 GB RAM)none1 GBInsurance without wasting disk I/O
PHP-FPM pm.max_childrenoften too highcalculatedPrevents RAM exhaustion at source

How do you optimize PHP, MySQL, and Laravel memory on a small VPS?

Swap prevents sudden death. Tuning prevents constant swapping. Swapping to disk kills response times and wears SSDs on budget hosts like affordable Hetzner Cloud VPS plans.

PHP-FPM pool sizing

Each PHP-FPM worker can use 50–150 MB for a Laravel 13 or WordPress 7.1 site. On 2 GB RAM with MySQL and Redis running, you cannot run 20 workers.

Estimate max children:

(Total RAM - MySQL - Redis - OS overhead) / average PHP worker size

Example for 2 GB RAM:

  • Reserve ~700 MB for MySQL
  • Reserve ~128 MB for Redis
  • Reserve ~400 MB for OS, Nginx, and buffers
  • Remaining ~770 MB ÷ 80 MB per worker ≈ 9 workers

Edit your pool file (path varies by PHP version):

sudo nano /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 9
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500

Set memory_limit in php.ini to match reality—256M is enough for most Laravel apps. See the dedicated guide on PHP memory limits and leak patterns for debugging runaway scripts.

MySQL buffer tuning

MySQL defaults assume a mid-size server. On a 1 GB VPS, innodb_buffer_pool_size at 128M is often safer than 512M or higher.

# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
max_connections = 50
table_open_cache = 200
performance_schema = OFF

Restart MySQL after changes: sudo systemctl restart mysql. Cross-check query load with advice from optimizing MySQL queries for high traffic.

Laravel and Redis on tight memory

On Laravel 12 or 13 apps, use Redis 8.10 for cache and sessions—not database sessions on every request. Queue workers should run under Supervisor with a single process on small boxes.

Disable unused services:

sudo systemctl disable --now snapd
sudo systemctl list-units --type=service --state=running

Commit built frontend assets in CI so production never runs Node.js 26 LTS builds. That pattern saves hundreds of megabytes during GitLab CI/CD deploys to a VPS.

I use this stack on sister sites sharing a Deployer 7 pipeline—legal portals like Notary Kathmandu and translation sites on the same EC2 host. Swap plus strict pool limits kept them stable through traffic spikes during filing seasons.

Before vs After Memory TuningBeforeAfterPHP 20 workers — 1.6 GBMySQL default — 800 MBNo swap — OOM riskPHP 9 workers — 720 MBMySQL tuned — 256 MB1 GB swap — safe2 GB VPS — available headroom grows from ~0 to ~400 MBResult: fewer 502 errors, stable cron, safer deploysSwap catches spikes; tuning reduces daily pressure
Memory optimization on a small VPS: right-size PHP-FPM and MySQL before relying on swap alone.

How do you monitor memory and avoid OOM kills?

After you add swap and tune services, monitor weekly. Memory leaks and traffic growth show up gradually until they do not.

Essential commands

free -h
htop
ps aux --sort=-%mem | head -15
sudo journalctl -k | grep -i "out of memory"
sudo dmesg -T | grep -i kill

For deeper analysis, follow the guide to diagnosing high CPU and memory usage. It covers pidstat, slow logs, and process trees.

Alerts worth setting

  • Email or Slack when available RAM stays below 150 MB for 5 minutes
  • Alert on MySQL restart events
  • Track PHP-FPM slow log growth
  • Monitor disk use—swap files consume real bytes

Log rotation matters too. An unbounded Laravel log on a 20 GB disk can fill the partition. Then swap cannot expand and MySQL cannot write temp tables. Pair memory work with database backup strategies for small servers so dumps do not run at peak traffic.

When to upgrade the VPS

If swap use stays above 30% during normal business hours, you are masking a capacity problem. A 2 GB plan running Rs 800–1,500/month (~USD 6–11) may need a bump to 4 GB. Compare options in a cloud cost optimization review before paying for idle RAM year-round.

WordPress migrations from managed hosting often land on undersized boxes. The WordPress migration to VPS hosting article covers plugin bloat that eats RAM on day one.

Swap Usage Decision TreeCheck: free -hSwap near 0%Normal hoursSwap above 30%Sustained useKeep tuning — you are OKUpgrade RAM or cut loadSpike during deploy only = swap is workingUse /tools/json-formatter to parse monitoring JSON exports
Monitor swap usage after you add a swap file: brief spikes are fine; sustained swap means upgrade or tune services.

File permissions and ownership gotchas

Memory problems sometimes look like permission errors. PHP cannot write sessions and spawns extra workers. Verify storage/ ownership on Laravel apps. The Ubuntu file permissions guide covers the www-data model I use on every deploy.

Wrong opcache settings after deploy can also inflate memory. Reload PHP-FPM after symlink swaps—the same step in my CI/CD best practices for small teams checklist.

Key Takeaways

  • Create a 1–2 GB swap file on Ubuntu, chmod 600, persist in /etc/fstab, and set vm.swappiness=10.
  • Calculate PHP-FPM pm.max_children from real worker size—not package defaults.
  • Lower MySQL innodb_buffer_pool_size on 1–2 GB VPS plans before the database consumes everything.
  • Watch journalctl -k for OOM kills; sustained swap use means upgrade or tune—not more swap.
  • Build assets in CI, disable unused systemd services, and keep logs rotated to preserve free RAM and disk.
  • Pair memory work with proper server support and maintenance so tuning survives the next framework upgrade.

People Also Ask

Is swap bad for SSD performance on a VPS?

Some swap use is normal on small servers. Heavy constant swapping wears SSDs and slows page loads. That is why you tune PHP and MySQL first and treat swap as emergency headroom—not a RAM replacement.

Can I use a swap partition instead of a swap file?

Yes. Partitions avoid filesystem overhead. On cloud VPS instances, a swap file is easier to resize without repartitioning. Most providers document swap files as the standard approach.

Does Docker change swap recommendations?

Containers add overhead. Each container runs its own processes. Budget an extra 200–400 MB for Docker on a 2 GB host, or run fewer containers per node. Swap sizing should account for the full stack, not one container.

What happens if my swap file fills up?

The kernel returns to OOM killing. Monitor with free -h and fix the root cause—usually too many PHP workers or an unbounded queue job. Adding more swap without tuning just delays the same crash.

Ship a stable small VPS without surprise downtime

You do not need a Rs 5,000/month (~USD 37) server to run a solid Laravel or WordPress site. You need to add a swap file and optimize memory on a small VPS before traffic finds your limits. Start with swap and swappiness today. Right-size PHP-FPM and MySQL this week. Monitor OOM logs monthly. If you want someone to audit a production box—or set up Deployer 7 with sane pool limits—see domain and hosting services or contact us for a memory and deployment review. For related reading, browse the blog archive, review Adventure Third Pole Trek on a tuned Laravel stack, or explore more about my DevOps work on Nepali and international projects.

Frequently Asked Questions

Swap is disk space the Linux kernel uses as overflow when physical RAM fills up. It is slower than RAM and acts as a safety net on web servers, not extra performance. On a typical stack with Nginx or Apache, PHP-FPM 8.3+, MySQL 8.4 or 9.7, Redis 8.10, and a queue worker, memory can exceed 1.5 GB during deploys or backups. Without swap, the OOM killer terminates processes like MySQL or heavy PHP workers, often causing random 502 errors that look like application bugs.

Add swap when your VPS has 4 GB RAM or less and runs multiple services like PHP-FPM, MySQL, Redis, and a queue worker. Skip ephemeral build containers.

Allocate 1–2 GB swap. Run df -h first—never allocate 4 GB swap on a 20 GB disk or logs and backups will fill the partition.

Set vm.swappiness between 10 and 20. Ubuntu default 60 is too high—RAM stays preferred and swap activates only under pressure.

These steps work on Ubuntu 22.04 and 24.04. Verify current swap with swapon --show. Create a 1 GB file with fallocate -l 1G /swapfile, chmod 600, mkswap, and swapon. If fallocate fails on your provider filesystem, use dd instead. Persist with an fstab entry: /swapfile none swap sw 0 0. Confirm with free -h and swapon --show after reboot. Wrong fstab syntax can boot into emergency mode—run mount -a to test and keep a provider console open during the first reboot.

Check dmesg or journalctl -k for Out of memory: Kill process messages. MySQL may restart without a clear error in its log. PHP-FPM logs show workers killed or server reached max_children. Run free -h during normal traffic—available memory near zero means you are one spike away from the OOM killer choosing MySQL or your heaviest PHP worker. I check swap and tuning first when a client reports random 502 errors on shared EC2 boxes.

Each PHP-FPM worker can use 50–150 MB on a Laravel 13 or WordPress 7.1 site. Calculate pm.max_children as total RAM minus MySQL, Redis, and OS overhead divided by average worker size. On 2 GB RAM, reserving 700 MB for MySQL, 128 MB for Redis, and 400 MB for OS leaves roughly 9 workers at 80 MB each. Set pm to dynamic with sensible start and spare servers, pm.max_requests to 500, and memory_limit in php.ini to 256M for most Laravel apps. Package defaults are often too high.

MySQL defaults assume a mid-size server. On a 1 GB VPS, innodb_buffer_pool_size at 128M is often safer than 512M. A practical mysqld.cnf baseline for tight boxes: innodb_buffer_pool_size 256M, innodb_log_file_size 64M, max_connections 50, table_open_cache 200, and performance_schema OFF. Restart MySQL after changes. Swap prevents sudden death from OOM kills, but right-sizing buffers prevents constant swapping that kills response times and wears SSDs on budget hosts.

On Laravel 12 or 13 apps, use Redis 8.10 for cache and sessions—not database sessions on every request. Run queue workers under Supervisor with a single process on small boxes. Disable unused services like snapd. Commit built frontend assets in CI so production never runs Node.js 26 LTS builds—that saves hundreds of megabytes during GitLab CI/CD deploys. I use this pattern on sister sites sharing a Deployer 7 pipeline on the same EC2 host; swap plus strict pool limits kept legal portals stable through filing-season traffic spikes.

Run free -h, htop, and ps aux sorted by memory weekly. Search journalctl -k and dmesg -T for out-of-memory and kill events. Set alerts when available RAM stays below 150 MB for five minutes, on MySQL restart events, and on PHP-FPM slow log growth. Monitor disk use—swap files consume real bytes, and an unbounded Laravel log on a 20 GB disk can fill the partition so MySQL cannot write temp tables. Brief swap spikes are fine; sustained use means tune or upgrade.

If swap use stays above 30 percent during normal business hours, you are masking a capacity problem—not fixing it. A 2 GB plan running Rs 800–1,500 per month (~USD 6–11) may need a bump to 4 GB. Compare cloud options before paying for idle RAM year-round. Adding more swap without tuning PHP-FPM and MySQL just delays the same crash. WordPress migrations from managed hosting often land on undersized boxes where plugin bloat eats RAM on day one.

Some swap use is normal on small servers and is cheap insurance when disk space is already paid for. Heavy constant swapping wears SSDs and slows page loads—that is why you tune PHP-FPM and MySQL first and treat swap as emergency headroom, not a RAM replacement. Right-size pm.max_children and innodb_buffer_pool_size before relying on swap alone. Monitor with free -h after setup; brief spikes during deploys or backups are acceptable, sustained swap during business hours is not.

Yes. Partitions avoid filesystem overhead and work fine on Linux. On cloud VPS instances, a swap file is easier to resize without repartitioning—most providers document swap files as the standard approach. Whether you use a partition or file, set vm.swappiness to 10–20, chmod 600 on the swap file, persist correctly in fstab, and verify after reboot. Wrong fstab syntax can boot your VPS into emergency mode, so test with mount -a before relying on it.

The kernel returns to OOM killing—same outcome as having no swap at all. Monitor with free -h and fix the root cause, usually too many PHP workers, MySQL buffers set too high, or an unbounded queue job. Adding more swap without tuning just delays the same crash. Calculate PHP-FPM max children from real worker size, cap MySQL innodb_buffer_pool_size on 1–2 GB plans, and keep a single Supervisor-managed queue worker on small boxes rather than stacking processes until disk overflow fails too.

Containers add overhead because each container runs its own processes. Budget an extra 200–400 MB for Docker on a 2 GB host, or run fewer containers per node. Swap sizing should account for the full stack—Nginx or Apache, PHP-FPM, MySQL, Redis, queue workers, and container runtime—not one container in isolation. The same swappiness guidance applies: 10–20 for web workloads. If swap use stays elevated during normal hours with Docker in the mix, upgrade RAM or reduce container count rather than growing swap indefinitely on a small disk.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: