PHP Performance Tuning for Small VPSes
Getting slow PHP performance on a small VPS? I'll walk you through the common bottlenecks and the practical steps I take to speed things up: from PHP-FPM configuration to opcode caching, with a focus on what works best for limited resources.
On this page
Slow PHP performance is a common headache, especially when you're running on a small VPS. I see it often on client boxes I usually manage. It’s not always a code problem; often, it’s a configuration issue. I’ll walk you through the common bottlenecks and the steps I take to speed things up, geared towards limited resources, specifically, environments like Ubuntu 24.04 or AlmaLinux 9.
PHP-FPM Configuration
PHP-FPM (FastCGI Process Manager) handles PHP execution. A misconfigured pool can kill performance. I usually start with the basics.
Pool Settings
Here's a simplified example of a PHP-FPM pool configuration. I'll assume you’re using the default pool, often found in /etc/php/8.3/fpm/pool.d/www.conf (adjust the 8.3 part to your PHP version).
[www]
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock; #Important: Check your socket path!
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500
request_terminate_timeout = 300
php_admin_value[error_log] = /var/log/php8.3/www-error.log
listen: This is critical. Make sure it matches the socket path Nginx (or Apache) is configured to use. Incorrect socket paths are a very common source of errors. You can usually find the correct path in your web server configuration. For example, in Nginx, it might be something like/etc/nginx/sites-available/default.pm:dynamicis often a good choice for VPSes as it adjusts the number of processes based on load.staticis simpler but less flexible.pm.max_children: This limits the number of PHP-FPM processes. Start low (around 5) and increase if you see errors or high load. Too many processes can overload your VPS.pm.max_requests: This limits the number of requests a worker process handles before being recycled. Helps prevent memory leaks. 500 is a reasonable starting point.request_terminate_timeout: How long PHP-FPM will wait for a request to finish. Adjust as needed based on your application's longest-running operations.
After making changes, reload PHP-FPM: sudo systemctl reload php8.3-fpm (again, adjust the PHP version).
Socket vs. TCP
PHP-FPM can listen on a Unix socket (like in the example) or a TCP port. Sockets are generally faster and more secure than TCP, so I prefer them. However, make sure your web server is configured to use the same method.
Opcode Caching
Opcode caching drastically improves performance by storing pre-compiled PHP code. OPcache is built into PHP and is almost always the best option.
Check your php.ini file (usually in /etc/php/8.3/cli/php.ini and /etc/php/8.3/fpm/php.ini).
[OPcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.validate_timestamps=0
opcache.revalidate_freq=60
opcache.enable: Must be1to enable OPcache.opcache.memory_consumption: How much memory OPcache can use. 128MB is usually sufficient for small VPSes. Don't allocate too much; leave memory for other processes.opcache.validate_timestamps: When set to0, OPcache will not check if the source files have been modified. This is generally safer for production, as it prevents invalidating the cache unnecessarily. Set to1during development.opcache.revalidate_freq: How often OPcache checks for file changes (whenopcache.validate_timestamps=1). 60 seconds is a good compromise.
Restart PHP-FPM after making changes: sudo systemctl reload php8.3-fpm
Database Optimization
Slow database queries are a huge performance killer. I usually check my database logs first. Make sure you have indexes on frequently queried columns. Use EXPLAIN to analyze query performance. This is especially important if you’re using MySQL/MariaDB.
My setup
On my servers, I keep a close eye on PHP-FPM memory usage with top or htop. I also regularly check the PHP error logs for any unusual activity. I don’t bother with more complex profiling tools unless I’m actively debugging a specific performance issue. I also consistently use the latest stable PHP version; it often includes performance improvements.
What went wrong (gotchas)
- Forgotten
systemctl reload: Changes tophp.inior PHP-FPM pool configurations won't take effect until you reload the services. A classic mistake. - Incorrect socket path: Double-check the socket path in both your PHP-FPM configuration and your web server configuration.
- Insufficient memory: If your VPS is constantly swapping, PHP performance will suffer. Consider upgrading your VPS or optimizing your code.
- File permissions: Incorrect file permissions can prevent PHP-FPM from accessing files. Make sure the
www-datauser has read access to your PHP files.
That's the basics of PHP performance tuning for small VPSes. It’s a continuous process, monitor, adjust, and repeat.
Now, check your PHP-FPM logs!
Related reading
Frequently asked questions
Why is my PHP website slow?
Slow PHP performance can be caused by several things, including inefficient code, a misconfigured PHP-FPM pool, missing opcode caching, or insufficient server resources. I usually start by checking the PHP error logs and using a profiler to identify bottlenecks.
How much RAM do I need for PHP-FPM?
It depends on your workload, but on a 2GB VPS, I rarely allocate more than 512MB to PHP-FPM. Over-allocating can waste resources that could be used elsewhere. Monitor memory usage and adjust as needed.
What's the best opcode cache for PHP?
OPcache is built into PHP since 5.5 and is generally the best choice. It's lightweight and effective for most use cases. I don't bother with alternatives unless I have a very specific, unusual need.
How can I monitor PHP performance?
Tools like New Relic and Blackfire are good, but often overkill for smaller sites. I usually rely on server monitoring tools (like htop) and PHP's built-in profiling tools to diagnose issues.