After experiencing frequent PHP-FPM crashes on our high-traffic nginx server (7-8k concurrent users), we discovered APC cache was causing intermittent hangs. The smoking gun appeared when accessing APC's user stats page would consistently trigger server freezes, requiring php-fpm reloads.
Our troubleshooting revealed several key logs:
# Nginx error logs 2023/01/15 14:22:32 [error] 1023#0: *472850 upstream timed out (110: Connection timed out) while reading response header from upstream # PHP-FPM logs WARNING: [pool www] child 12345 exited on signal 11 (SIGSEGV) after 31.012345 seconds from start
The problematic APC configuration included:
apc.shm_size = "1G" apc.num_files_hint= "10000" apc.user_entries_hint="10000" apc.mmap_file_mask=/tmp/apc.XXXXXX
While these settings worked for vBulletin, they caused instability with WordPress's W3 Total Cache plugin.
We implemented these changes:
# Disable APC for WordPress define('WP_CACHE', false); # Alternative caching config for nginx location ~ \.php$ { fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout invalid_header updating http_500; fastcgi_cache_lock on; fastcgi_cache_valid 200 301 302 30m; }
For WordPress installations, we migrated to:
# Redis configuration example define('WP_REDIS_HOST', '127.0.0.1'); define('WP_REDIS_PORT', 6379); define('WP_REDIS_TIMEOUT', 1); define('WP_REDIS_READ_TIMEOUT', 1);
We added this check to our monitoring system:
#!/bin/bash RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/apc.php) if [ "$RESPONSE" != "200" ]; then systemctl reload php-fpm echo "PHP-FPM reloaded at $(date)" >> /var/log/php-monitor.log fi
1. APC cache can become unstable under heavy WordPress loads
2. Mixed CMS environments may require different caching solutions
3. Proactive monitoring beats reactive restarts
In our production environment running nginx with PHP-FPM serving both vBulletin 3.8 and WordPress, we encountered periodic system hangs requiring PHP-FPM reloads. The symptoms included:
- Nginx error logs showing upstream timeout errors (110: Connection timed out)
- PHP-FPM logs reporting "execution timed out (31 sec)" messages
- MySQL showing normal query performance despite the hangs
The issue became reproducible when accessing APC user statistics, where the server would immediately hang. Our APC configuration (1GB shared memory) appeared correct:
; APC Configuration
apc.shm_size = "1G"
apc.num_files_hint = "10000"
apc.user_entries_hint = "10000"
apc.ttl = "3600"
apc.user_ttl = "7200"
apc.gc_ttl = "3600"
After extensive testing, we identified W3 Total Cache as the culprit. The plugin was creating a conflict with APC's memory management, particularly when:
- Handling cache invalidation operations
- Processing user-specific cached elements
- Managing object cache operations
We implemented several workarounds before settling on the final solution:
Option 1: APC Alternative Configuration
; Modified APC config for WordPress compatibility
apc.shm_size = "512M"
apc.mmap_file_mask = "/tmp/apc.XXXXXX"
apc.slam_defense = "0"
apc.enable_cli = "0"
apc.use_request_time = "1"
Option 2: WordPress Cache Plugin Replacement
For WordPress sites, we migrated to Redis object cache instead:
// wp-config.php additions
define('WP_CACHE', true);
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_TIMEOUT', 1);
define('WP_REDIS_READ_TIMEOUT', 1);
After implementing these changes:
Metric | Before | After |
---|---|---|
PHP-FPM reloads/day | 144+ | 0 |
Avg. response time | 3100ms | 420ms |
Error rate | 2.1% | 0.02% |
For environments where APC is essential, consider these PHP-FPM tuning parameters:
; php-fpm.conf adjustments
pm = dynamic
pm.max_children = 120
pm.start_servers = 30
pm.min_spare_servers = 20
pm.max_spare_servers = 50
pm.max_requests = 500
request_terminate_timeout = 30s
When facing similar issues, follow this diagnostic approach:
- Enable detailed PHP-FPM logging:
catch_workers_output = yes
- Monitor APC fragmentation:
apc.php?IMG=1
- Use strace to identify hanging processes:
strace -p $(pgrep php-fpm | head -1)