Optimizing PHP-FPM on a Low-Memory VPS: Pool Tuning and OpCache Configuration

PHP-FPM is the most common execution model for PHP applications on VPS instances, but default configurations are tuned for dedicated servers with ample memory. This tutorial covers optimizing PHP-FPM for 1-4 GB VPS environments, balancing concurrency against memory pressure.

Choosing the Right Process Manager Model

PHP-FPM offers three process management models in pm directive within /etc/php/*/fpm/pool.d/www.conf:

  • static: Fixed number of child processes. Best for consistent traffic loads on VPS with predictable resource allocation.
  • dynamic: Adjusts children between min/max bounds. Good for variable traffic but can thrash under rapid load changes.
  • ondemand: Spawns children on demand, kills idle ones. Lowest memory footprint but adds latency for cold requests.

For low-memory VPS (1-2 GB), ondemand is often the best starting point. Calculate your per-process memory usage first:

# Check PHP-FPM memory per process
ps aux | grep php-fpm | grep -v grep | awk '{sum+=$6; count++} END {print "Avg MB per process:", sum/count/1024}'

# Typical output for a WordPress site: Avg MB per process: 35-50MB

Pool Configuration for 1-2 GB VPS

Example www.conf settings for a 1 GB VPS running WordPress or Laravel:

pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 30s
pm.max_requests = 500

; Prevent memory leaks by recycling processes
pm.status_path = /status

; Security hardening
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Timeouts";
request_terminate_timeout = 120
request_slowlog_timeout = 10
slowlog = /var/log/php7.4-fpm-slow.log

For a 2 GB VPS with higher traffic, use the dynamic model:

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6

OpCache Configuration for Maximum Throughput

PHP’s OpCache caches compiled PHP bytecode, eliminating the parse phase on every request. Configure in /etc/php/*/cli/conf.d/10-opcache.ini:

opcache.enable=1
opcache.memory_consumption=64
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.validate_timestamps=0
opcache.save_comments=1

Key settings explained:

  • memory_consumption=64: 64 MB for OpCache on a low-memory VPS. Increase to 128 MB for larger codebases.
  • interned_strings_buffer=8: 8 MB for interned strings. Save space by sharing identical string instances.
  • max_accelerated_files=4000: Sufficient for most CMS installations. Check with opcache_get_status() whether your hit rate exceeds 95%.
  • validate_timestamps=0: Disable file-change checking in production for maximum performance. Clear cache manually after deployments.

Monitoring PHP-FPM Performance

Enable the status page to monitor pool activity:

# In your Nginx config for the FPM pool
location /status {
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Access https://your-vps/status?full to see per-process details. Key metrics: active processes, max children reached, and total processes. If max children reached increments, you need more pool capacity or better caching.

For holistic VPS performance tuning including database and web server optimization, see our complete VPS optimization guide.

Leave a Reply