in

Optimizing PHP-FPM for High Performance


PHP is one of the most popular server-side scripting languages used for web development. It powers millions of websites across the internet, including WordPress, Drupal, Magento and many more.

However, PHP is not inherently optimized for high performance and scalability out of the box. This is where PHP-FPM comes in.

PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation focused on performance. It is the preferred method of running PHP for high traffic websites and web applications.

In this comprehensive guide, we will dive into how to optimize PHP-FPM for maximum performance and scalability.

What is PHP-FPM and How Does it Work?

To understand how to optimize PHP-FPM, we first need to understand what it is and how it works under the hood.

PHP-FPM is a daemon process manager that handles PHP requests independently from the web server. It manages multiple PHP worker processes and recycles them between requests for better performance.

Here is a high-level overview of what happens when a request comes in:

  1. The web server (e.g. Nginx) receives the request from the client.

  2. Nginx passes the request to PHP-FPM via a FastCGI protocol.

  3. PHP-FPM initializes a PHP worker process from its process pool to handle the request.

  4. The PHP script is executed by the worker process.

  5. Output is passed back to Nginx via FastCGI.

  6. Nginx sends the response back to the client.

  7. Once finished, the PHP worker process is returned back to the pool for reuse.

This is more efficient than the older mod_php approach, where PHP is embedded in the web server process and cannot be managed independently.

Some key advantages of PHP-FPM include:

  • Better process management – The PHP worker pool can be fine-tuned for optimal performance.

  • Memory savings – PHP processes are recycled instead of restarted per request. This saves memory especially for long-running processes.

  • Increased throughput – More requests can be handled simultaneously since PHP execution is separate from the web server.

  • Improved stability – If PHP crashes, the web server can continue to serve other PHP-FPM pools or static files.

Understanding how PHP-FPM operates sets the foundation for tuning it for maximum performance.

PHP-FPM Configuration and Optimization

The main PHP-FPM configuration file is usually /etc/php-fpm.conf or /etc/php-fpm.d/www.conf on Linux systems. This controls global settings and the configuration for each pool.

Here are the key things we can optimize:

1. Tune pm (Process Manager) Settings

The pm settings control how the PHP-FPM worker processes are managed:

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35  

pm – Set this to dynamic which is ideal for most scenarios. ondemand can also be used for low traffic sites.

pm.max_children – Maximum number of worker processes that can be open simultaneously. Set this appropriately high based on your traffic load.

pm.start_servers – Number of processes launched at startup. Can be set to a low value since the process pool expands dynamically per load.

pm.min_spare_servers – Minimum number of idle processes maintained in the pool. Avoid setting this too high.

pm.max_spare_servers – Maximum number of idle processes before exceeding ones are killed. Tweak together with the above settings to optimize idle process count.

Tuning these values allow PHP-FPM to scale up and down smoothly while making efficient use of system resources.

2. Adjust pm.max_requests

The pm.max_requests setting specifies how many requests a worker process should handle before being recycled:

pm.max_requests = 500

A value between 500-1000 is good depending on your typical request execution time. Recycling workers regularly helps prevent memory leaks.

You can set this to 0 to disable automatic recycling, but this is not recommended. Make sure to tune this based on your application behavior.

3. Increase pm.status_path Requests Limit

The pm.status_path exposes a URL to monitor the status of PHP-FPM pools (/status). For example:

pm.status_path = /status

However, this path is limited to only handling a few requests per second by default. Increase its request handling capacity by setting:

pm.max_children = 50
pm.max_requests = 500

This allows more parallel monitoring requests to the status page.

4. Tweak php.ini Settings

Many PHP performance optimizations can be made by tweaking php.ini values:

  • Increase memory_limit based on your application needs.
  • Adjust max_execution_time to allow longer running processes if required.
  • Reduce realpath_cache_size and realpath_cache_ttl if dealing with a large number of file paths.
  • Increase opcache settings like opcache.memory_consumption for better opcode caching.

Experiment with tuning these based on your specific PHP application‘s behavior.

5. Enable Opcode Caching

Enabling opcode caching via OPcache greatly speeds up PHP execution:

opcache.enable=1

Other useful OPcache settings to configure include:

  • opcache.memory_consumption – Increase for better hit rate.
  • opcache.interned_strings_buffer – Set to 16-64 MB to store strings in shared memory.
  • opcache.max_accelerated_files – Bump up from default 4000 limit if required.
  • opcache.validate_timestamps – Set to 0 to disable costly file timestamp checks.

Tweaking OPcache is one of the most effective ways to boost PHP-FPM performance.

6. Preload PHP Scripts

OPcache provides the ability to preload PHP scripts on startup:

opcache.preload=/path/to/app

This precompiles your application code on bootup for much faster execution during requests.

7. Improve Logging Configuration

It‘s important to set up effective logging to monitor PHP-FPM health:

access.log = /var/log/php-fpm/access.log
slowlog = /var/log/php-fpm/slow.log

Access logs record all requests while slow logs catch any slow executions exceeding a threshold:

; log slow requests taking longer than 60 seconds
request_slowlog_timeout = 60s

Proper logging enables identifying and troubleshooting any PHP-FPM bottlenecks or issues.

Advanced PHP-FPM Optimization Tips

Here are some additional optimizations for pushing PHP-FPM performance further:

  • Run multiple PHP-FPM pools with different pm configs on multicore boxes to isolate requests across CPU cores.

  • Enable APCu caching to store common objects in memory instead of rediscovering them on each request.

  • Pre-resolve paths used in scripts via realpath_cache_* to avoid extra filesystem lookups.

  • Separate out static assets to be served directly by the web server instead of going via PHP.

  • Cache database query results in Redis/Memcached to reduce database trips.

  • Use asynchronous PHP workers like ReactPHP to speed up queued jobs/tasks handling.

  • Distribute load across multiple PHP-FPM boxes via Load Balancing.

  • Enable PHP Zend Thread Safety and parallel processing if supported by your application.

  • Limit segments of code execution time with set_time_limit() to prevent one slow section from blocking others.

  • Profile code with Xdebug/Blackfire and optimize bottlenecks in the application logic itself.

  • Use opcode compilers like Phalanger or HipHop VM for increased execution performance of PHP code.

  • Shift from PHP to Go, Elixir, Rust or other high-performance languages where possible.

As you can see, optimizing PHP-FPM opens up many possibilities for pushing PHP performance to the limits.

Measuring PHP-FPM Performance Improvements

It‘s critical to measure before and after metrics when optimizing PHP-FPM to validate the impact of changes:

Benchmark Tools

  • Apache Bench – Basic load testing tool for generating requests.
  • JMeter – Open source load and performance testing app.
  • BlazeMeter – Enterprise grade performance testing platform.

Metrics to Monitor

  • Requests per second
  • Latency per request
  • Error rates
  • Memory usage
  • CPU usage

Monitoring PHP-FPM

  • Check /status page provided by PHP-FPM for pool stats.
  • Logs – Monitor access logs and slow logs for anomalies.
  • New Relic – Application monitoring agent with PHP support.
  • Blackfire – Detailed profiler to identify PHP bottlenecks.

Continuously measuring key performance metrics is vital to ensure optimizations deliver expected benefits.

Conclusion

Optimizing PHP-FPM provides a powerful method to achieve blazing fast PHP performance and scale websites.

Follow the tips outlined in this guide to get started tuning your PHP-FPM config. Try out different settings across live traffic and benchmarks to validate improvements.

With careful tuning, you can squeeze out every last bit of performance from your PHP application and infrastructure. The end result is a highly optimized PHP environment capable of delivering lightning fast response times and handling heavy request loads.

AlexisKestler

Written by Alexis Kestler

A female web designer and programmer - Now is a 36-year IT professional with over 15 years of experience living in NorCal. I enjoy keeping my feet wet in the world of technology through reading, working, and researching topics that pique my interest.