
September 10, 2026
11 min read
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:
dmesgorjournalctl -kshows "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 -hshows 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.
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
- Verify current swap:
sudo swapon --show - Create a 1 GB file (change
1Gif 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.
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.
| Setting | Default | Web VPS recommendation | Why |
|---|---|---|---|
| vm.swappiness | 60 | 10–20 | Keeps hot PHP and MySQL pages in RAM |
| vm.vfs_cache_pressure | 100 | 50–100 | Reclaims filesystem cache under pressure |
| Swap size (1 GB RAM) | none | 1 GB | Covers deploy and backup spikes |
| Swap size (4 GB RAM) | none | 1 GB | Insurance without wasting disk I/O |
| PHP-FPM pm.max_children | often too high | calculated | Prevents 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.
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.
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 setvm.swappiness=10. - Calculate PHP-FPM
pm.max_childrenfrom real worker size—not package defaults. - Lower MySQL
innodb_buffer_pool_sizeon 1–2 GB VPS plans before the database consumes everything. - Watch
journalctl -kfor 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
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.

