To optimize web server performance on a VPS, you need to work across four layers: the HTTP server (Apache or Nginx), the PHP interpreter, the caching layer, and the operating system itself. Methodical changes at each layer can cut response times in half or more.
This guide covers the highest-impact adjustments you can make today — no hardware upgrade or provider migration required.
1. Baseline audit: measure before you touch anything
Optimizing without data is guesswork. Before making any changes, capture your server's current state.
Essential diagnostic tools
- top / htop — real-time CPU and RAM usage.
- vmstat 1 5 — disk, memory and CPU activity per second.
- ab (Apache Benchmark) — basic load test:
ab -n 500 -c 20 https://yourdomain.com/. - curl -o /dev/null -w "%{time_total}" — single-request response time.
- mysqltuner.pl — targeted recommendations for MariaDB/MySQL.
Record your baselines: average response time, requests per second (RPS), and RAM usage under load. These numbers are your benchmark.
2. HTTP server tuning: Apache and Nginx
The HTTP server handles every incoming request. A poor configuration here cancels out gains made elsewhere.
Apache: modules and MPM
Disable unused modules — each loaded module consumes RAM:
a2dismod autoindex status userdir
a2enmod expires headers deflate
Switch from MPM Prefork (blocking) to MPM Event if you use PHP-FPM. MPM Event handles keep-alive connections without tying up a full process per connection.
Set reasonable worker limits for your available RAM. On a 2 GB VPS:
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 1000
</IfModule>
Nginx: worker_processes and gzip
Set worker_processes to match your CPU cores and enable gzip compression to reduce response payload size:
worker_processes auto;
gzip on;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript text/xml;
Also enable sendfile on; and tcp_nopush on; for efficient static file serving.
3. Caching: the highest-leverage change
No code-level tweak improves performance as dramatically as returning a cached response. Implement caching at two levels minimum.
Opcode cache (OPcache)
PHP compiles every .php file to bytecode on each request unless OPcache is active. Enable it in php.ini:
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
With OPcache, the interpreter skips compilation and serves bytecode from memory. For PHP sites, the impact is immediate and substantial.
Object caching with Redis or Memcached
For applications that run many repeated database queries, an in-memory store like Redis reduces database server load dramatically:
- Install Redis:
dnf install redis(orapt install redis-server). - Connect your PHP application via the
phpredisextension. - Cache results of expensive queries with a sensible TTL.
Full-page cache
If your site has mostly static content (blog, landing pages), serve pre-generated HTML directly from Nginx without invoking PHP at all:
location / {
try_files /cache/$uri/index.html $uri $uri/ /index.php?$args;
}
WordPress users can achieve this automatically with WP Super Cache or W3 Total Cache. For a broader overview of VPS server management strategies, browse our VPS servers resource hub.
4. PHP-FPM: pool configuration
PHP-FPM manages the worker processes that interpret your PHP code. A poorly tuned pool creates a bottleneck even if the HTTP server is well configured.
Process manager: dynamic vs ondemand
| Mode | Best for | Advantage |
|---|---|---|
| static | High, predictable traffic | No process-start latency |
| dynamic | Variable traffic | Balance between RAM and capacity |
| ondemand | Small VPS / multiple sites | Minimum RAM when idle |
For a 2–4 GB VPS hosting multiple sites, ondemand or conservative dynamic settings work best:
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500
pm.max_requests = 500 recycles processes to prevent memory leaks in older PHP applications.
5. Database and OS-level tuning
MariaDB / MySQL: key variables
Slow database queries degrade overall server performance. Enable the slow query log and tune the buffer pool:
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
innodb_buffer_pool_size = 512M # ~50–70% of available RAM
innodb_log_file_size = 128M
query_cache_type = 0 # disable query cache (obsolete in MySQL 8)
Add indexes on columns used in WHERE, ORDER BY, or JOIN clauses of your most frequent queries.
Linux OS tweaks
Several kernel parameters can limit performance under high load:
- Open file limit: increase in
/etc/security/limits.conf(* soft nofile 65535). - TCP reuse: reduce TIME_WAIT connections with
net.ipv4.tcp_tw_reuse = 1in/etc/sysctl.conf. - Swappiness: on web servers, lower to 10 to prefer RAM over swap:
vm.swappiness = 10.
Key takeaways
- Always measure first — without baselines you cannot tell if your changes worked.
- OPcache delivers the highest ROI for any PHP site: enable it before anything else.
- Tune Apache MPM or Nginx worker_processes to match your VPS's actual RAM.
- PHP-FPM in dynamic or ondemand mode balances performance and memory consumption.
- Redis or Memcached dramatically reduce database load on query-heavy apps.
- MariaDB/MySQL buffer variables and Linux kernel parameters are the final tuning layer.
If you'd rather have an expert team handle this for you, elenlace.com offers managed VPS services for agencies and businesses in Mexico — reach out and tell us about your setup.
FAQ
How much RAM does a VPS need for a medium-traffic website?
For a site with 10,000–50,000 monthly visitors, a 2–4 GB VPS is usually sufficient with proper configuration. In most cases the bottleneck is misconfiguration, not hardware.
Does OPcache work with all PHP frameworks?
Yes. OPcache operates at the interpreter level, so it is fully compatible with Laravel, Symfony, WordPress, Magento, and any PHP code without changes to your application.
Is Nginx always faster than Apache?
Nginx uses less memory under high concurrency (many simultaneous connections). Apache with MPM Event and PHP-FPM is competitive in most real-world scenarios. The difference matters primarily when you reach hundreds of simultaneous connections.
How often should I review my server's performance?
Run a monthly check of core metrics (CPU, RAM, response times) and do a deep review whenever you launch a new feature or traffic grows by more than 30%.
Prefer it done for you? El Enlace handles hosting and professional web development.
Useful resources
Other providers and guides worth comparing: