Skip to content
intermediate Phase 97 · Deployment

PHP-FPM Configuration for Magento

PHP-FPM configuration for Magento including pool settings, worker management, performance tuning, and monitoring

45m
0 problems
Topic Progress 0%

PHP-FPM Pool Configuration

Pool Configuration File

; /etc/php/8.1/fpm/pool.d/magento.conf
[magento]

; Pool name
; Used in Nginx fastcgi_pass

; Unix socket
listen = /var/run/php/php8.1-fpm-magento.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Or TCP
; listen = 127.0.0.1:9000

; Process management
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500

; Timeouts
request_terminate_timeout = 300s
request_slowlog_timeout = 5s

; Logging
slowlog = /var/log/php-fpm/magento-slow.log
php_admin_value[error_log] = /var/log/php-fpm/magento-error.log
php_admin_flag[log_errors] = on

; Memory
php_admin_value[memory_limit] = 756M

; OPcache
php_admin_value[opcache.enable] = 1
php_admin_value[opcache.memory_consumption] = 256M
php_admin_value[opcache.max_accelerated_files] = 20000

Pool Modes

; static: Fixed number of children
pm = static
pm.max_children = 50

; dynamic: Adjusts based on load
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20

; ondemand: Creates children on demand
pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 10s

Socket vs TCP

; Unix socket (faster, same server)
listen = /var/run/php/php8.1-fpm-magento.sock

; TCP (network access, multiple servers)
listen = 127.0.0.1:9000

Key Takeaway

PHP-FPM pools define how PHP processes are managed. Use dynamic mode with appropriate max_children based on server memory. Unix sockets are faster than TCP for same-server communication.

Worker Management

Worker Calculation

# Formula: max_children = Available RAM / PHP per process

# Example:
# Server RAM: 8GB
# OS/Services: 2GB
# Available for PHP: 6GB
# PHP per process: 756MB
# Max children: 6GB / 756MB = ~8

# More conservative (with headroom):
# Max children = Available RAM / (PHP memory * 1.2)
# 6GB / (756MB * 1.2) = ~6

Worker Monitoring

# Check PHP-FPM status
sudo systemctl status php8.1-fpm

# Check pool status
curl http://localhost/fpm-status

# Check active processes
ps aux | grep php-fpm

# Count PHP-FPM processes
ps aux | grep -c 'php-fpm: pool'

Status Page Configuration

; Add to pool config
pm.status_path = /fpm-status
ping.path = /fpm-ping
ping.response = pong

; Enable in Nginx
location ~ ^/(fpm-status|fpm-ping)$ {
    access_log off;
    allow 127.0.0.1;
    deny all;
    fastcgi_pass unix:/var/run/php/php8.1-fpm-magento.sock;
    include fastcgi_params;
}

Process Management Commands

# Restart PHP-FPM
sudo systemctl restart php8.1-fpm

# Reload configuration (graceful)
sudo systemctl reload php8.1-fpm

# Stop PHP-FPM
sudo systemctl stop php8.1-fpm

# Check configuration
sudo php-fpm8.1 -t

Worker Scaling

# Monitor and adjust based on traffic

# Peak hours: increase start_servers
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30

# Off-peak: decrease to save memory
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 10

Key Takeaway

Calculate max_children based on available RAM and PHP memory limit. Use status page for monitoring. Adjust workers based on traffic patterns.

Performance Tuning

OPcache Configuration

; /etc/php/8.1/fpm/conf.d/10-opcache.ini
[opcache]
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.max_wasted_percentage=10
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.save_comments=1
opcache.fast_shutdown=1

Memory and Execution Limits

; /etc/php/8.1/fpm/php.ini
memory_limit = 756M
max_execution_time = 300
max_input_time = 300
post_max_size = 100M
upload_max_filesize = 100M
max_file_uploads = 20

Realpath Cache

; Increase realpath cache
realpath_cache_size = 4096K
realpath_cache_ttl = 600
``n
## Slow Log Analysis

```bash
# Enable slow log
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log

# Analyze slow log
awk '/^\[.*\]$/{ts=$0} /script_filename/{print ts, $0}' /var/log/php-fpm/slow.log | sort | uniq -c | sort -rn | head -20

OPcache Invalidation

# Clear OPcache
echo '<?php opcache_reset(); ?>' | sudo php

# Or restart PHP-FPM
sudo systemctl restart php8.1-fpm

Key Takeaway

Tune OPcache for compiled code caching, increase memory limits for Magento, configure realpath cache, and analyze slow logs for bottlenecks.

Monitoring and Debugging

Health Checks

#!/bin/bash
# php-fpm-health.sh

# Check PHP-FPM is running
if ! systemctl is-active php8.1-fpm > /dev/null; then
    echo "PHP-FPM is not running!"
    exit 1
fi

# Check socket exists
if [ ! -S /var/run/php/php8.1-fpm-magento.sock ]; then
    echo "PHP-FPM socket not found!"
    exit 1
fi

# Check status page
STATUS=$(curl -s http://localhost/fpm-status | head -1)
if [ -z "$STATUS" ]; then
    echo "PHP-FPM status page not responding!"
    exit 1
fi

echo "PHP-FPM is healthy"

Monitoring Metrics

# Key metrics to monitor
# 1. Process count
ps aux | grep -c 'php-fpm: pool'

# 2. Memory usage
ps aux | grep php-fpm | awk '{sum+=$6} END {print sum/1024 " MB"}'

# 3. Active connections
# Check FPM status page for 'active processes'

# 4. Slow requests
wc -l /var/log/php-fpm/slow.log

Debugging PHP-FPM

# Check error logs
tail -f /var/log/php-fpm/magento-error.log

# Check slow logs
tail -f /var/log/php-fpm/magento-slow.log

# Check PHP errors
tail -f /var/log/php/8.1/fpm/error.log

# Debug mode
php -d display_errors=1 -d error_reporting=E_ALL script.php

Common Issues and Fixes

# Issue: Too many workers
# Fix: Reduce pm.max_children or increase server RAM

# Issue: Slow requests
# Fix: Increase request_terminate_timeout, optimize code

# Issue: Socket not found
# Fix: Check listen configuration, restart PHP-FPM

# Issue: Memory exhaustion
# Fix: Reduce memory_limit or max_children

Key Takeaway

Monitor PHP-FPM health with status pages and scripts. Analyze slow logs for performance issues. Debug with error logs and PHP debug mode.

Quiz

1. How do you calculate PHP-FPM max_children?

Question 1 options

2. What is the difference between Unix socket and TCP?

Question 2 options

3. What does pm.status_path do?

Question 3 options

4. Why use 'pm = dynamic' for Magento?

Question 4 options

5. What does request_slowlog_timeout do?

Question 5 options

Flashcards

Question

How to calculate max_children?

Answer

Available RAM / PHP memory_limit per process (e.g., 6GB / 756MB = ~8)

Question

Unix socket vs TCP?

Answer

Unix socket faster for same server, TCP for network access

Question

What is pm.status_path?

Answer

Enables status page showing pool statistics for monitoring

Question

Why use dynamic PM mode?

Answer

Adjusts workers based on traffic, balancing performance and memory

Question

What does request_slowlog_timeout do?

Answer

Logs requests exceeding threshold for performance debugging

Question

How to reload PHP-FPM gracefully?

Answer

sudo systemctl reload php8.1-fpm (no downtime)

Question

What is OPcache?

Answer

Caches compiled PHP code in memory for faster execution

Question

How to clear OPcache?

Answer

echo '<?php opcache_reset(); ?>' | sudo php

Revision Notes

Key Takeaways

  • 1. Calculate max_children based on available RAM and PHP memory
  • 2. Use Unix sockets for same-server, TCP for network
  • 3. Enable status page for monitoring
  • 4. Configure OPcache for compiled code caching
  • 5. Analyze slow logs for performance issues

Interview Tips

  • Explain PHP-FPM pool configuration
  • Discuss worker calculation and scaling
  • Describe OPcache optimization
  • Explain monitoring and debugging approaches

Cheat Sheet

PHP-FPM Config

Pool Settings:
listen = /var/run/php/php8.1-fpm.sock
pm = dynamic
pm.max_children = RAM / memory_limit

Performance:
opcache.enable = 1
opcache.memory_consumption = 256M
opcache.max_accelerated_files = 20000

Monitoring:
pm.status_path = /fpm-status
slowlog = /var/log/php-fpm/slow.log

Commands:
sudo systemctl reload php8.1-fpm
sudo php-fpm8.1 -t
ps aux | grep php-fpm