Optimizing High-Traffic PHP-FPM and Nginx Configuration to Resolve “Resource Temporarily Unavailable” Socket Errors


2 views

When stress testing at 200 requests/second, the system exhibits a classic degradation pattern:

499 errors → 502 Bad Gateway → php-fpm.sock connection failures (EAGAIN/EWOULDBLOCK)

The key error connect() to unix://...php-fpm.sock failed (11: Resource temporarily unavailable) indicates Linux kernel's connection queue is exhausted. Three critical limits interact here:

1. net.core.somaxconn (default: 128)
2. php-fpm's listen.backlog (your setting: 65535)
3. nginx worker_connections (your setting: 16192)

Add these to /etc/sysctl.conf:

net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
fs.file-max = 2097152

Apply with sysctl -p. Verify with:

sysctl net.core.somaxconn

Your current dynamic PM settings may cause thrashing. Consider this production-tuned configuration:

[www]
listen = /var/run/php-fpm/php-fpm.sock
listen.backlog = 32768
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

pm = ondemand
pm.max_children = 1200
pm.process_idle_timeout = 10s
pm.max_requests = 1000

Key changes:

  • Switch from dynamic to ondemand PM
  • Realistic max_children based on RAM (≈50MB/process)
  • Proper backlog alignment with kernel

Add these directives in your server block:

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
    fastcgi_connect_timeout 60s;
    fastcgi_send_timeout 180s;
    fastcgi_read_timeout 180s;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 256 16k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_max_temp_file_size 0;
    fastcgi_keep_conn on;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

For CentOS 7, create /etc/systemd/system/php-fpm.service.d/10-socket.conf:

[Service]
LimitNOFILE=65535
ExecStartPre=/bin/bash -c "test -S /var/run/php-fpm/php-fpm.sock && rm /var/run/php-fpm/php-fpm.sock"

Then reload systemd:

systemctl daemon-reload
systemctl restart php-fpm nginx

Use this benchmark command to validate improvements:

wrk -t12 -c400 -d60s --latency http://yourdomain.com

Monitor socket states during test:

watch -n1 "ss -xlp | grep php-fpm"

When testing with 200 requests per second, the system exhibits a clear error progression:

  • Initial 499 errors (client closed request)
  • Followed by 502 Bad Gateway errors
  • Finally culminating in PHP-FPM socket connection failures

The critical error message reveals:

connect() to unix:///var/www/vhosts/system/playhdpk.top/php-fpm.sock 
failed (11: Resource temporarily unavailable)

The server specifications (Xeon E5-1620v2, 64GB RAM) suggest hardware isn't the limiting factor. The issues stem from three configuration areas:

PHP-FPM Pool Settings

The current configuration:

pm = dynamic
pm.max_children = 5000  # Excessive for most setups
pm.start_servers = 50
pm.min_spare_servers = 20
pm.max_spare_servers = 70
pm.max_requests = 2000
listen.backlog = 65535

Nginx Configuration Issues

Key parameters affecting PHP-FPM communication:

worker_connections 16192;
fastcgi_buffers 8 128k;
fastcgi_buffer_size 256k;

1. PHP-FPM Socket Tuning

Adjust the pool configuration:

; Optimized for 200 RPS:
pm = dynamic
pm.max_children = 200  # Should be ~20-30% of available RAM divided by average PHP process size
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 500  # Prevents memory leaks
listen.backlog = 511  # Should be <= somaxconn
listen.mode = 0660

2. Kernel-Level Socket Adjustments

Add to /etc/sysctl.conf:

net.core.somaxconn = 2048
net.ipv4.tcp_max_syn_backlog = 2048
net.core.netdev_max_backlog = 4096
fs.file-max = 100000

Apply with sysctl -p

3. Nginx FastCGI Optimization

fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 64k;
fastcgi_temp_file_write_size 128k;
fastcgi_connect_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_read_timeout 300s;

Monitor PHP-FPM status during load testing:

watch -n1 'ps -ylC php-fpm --sort:rss | head -20'
ss -pl | grep php-fpm.sock
netstat -antp | grep php-fpm

Here's a load testing command that simulates 200 RPS:

ab -c 200 -n 10000 http://yoursite.com/

Monitor with:

dstat -tcmnd --top-bio --top-cpu

For extreme workloads, implement socket sharding:

; In php-fpm.conf
include=/etc/php-fpm.d/*.conf

; Then create multiple pool files:
; /etc/php-fpm.d/pool-01.conf
listen = /var/run/php-fpm/php-fpm-01.sock
; /etc/php-fpm.d/pool-02.conf
listen = /var/run/php-fpm/php-fpm-02.sock

After changes, verify with:

php-fpm -t  # Test configuration
nginx -t    # Test Nginx config
systemctl restart php-fpm nginx