# MaplePress Performance Optimization Guide ## Understanding WordPress Performance Bottlenecks MaplePress offloads search processing to our cloud infrastructure, but your WordPress site's ability to **handle concurrent requests** determines the actual user experience. Even with our lightning-fast backend (< 20ms processing time), users may experience slow response times if WordPress itself is the bottleneck. --- ## The #1 Bottleneck: PHP-FPM Worker Starvation ### What is PHP-FPM? **PHP-FPM** (FastCGI Process Manager) is the process manager that handles PHP requests in WordPress. It uses a pool of "worker" processes to execute PHP code. **Think of it like a restaurant:** - **Chef (PHP-FPM worker)** = processes one request at a time - **Order (HTTP request)** = incoming search/page load If you have **5 chefs** and **25 orders arrive simultaneously**, only 5 orders get processed immediately. The other 20 orders **wait in line** (queue), even if each order only takes 200ms to prepare. ### Real-World Impact **Common Default Configuration:** ```ini pm.max_children = 5 # Only 5 workers! ``` **What This Means:** - **Concurrent users**: 25 people search simultaneously - **Workers available**: Only 5 - **Result**: 20 requests wait in queue - **User experience**: 8-10 second response times (even though backend is fast!) **Performance Comparison (25 concurrent searches):** | Configuration | Workers | Response Time | Queue Time | |--------------|---------|---------------|------------| | **Default** | 5 | 8,000-9,000ms | ~7,800ms waiting | | **Optimized** | 50 | 300-500ms | No waiting ✅ | **52x faster** just by increasing workers! --- ## Solution: Increase PHP-FPM Workers ### Step 1: Check Current Configuration SSH into your WordPress server: ```bash # For standard PHP-FPM installations sudo cat /etc/php/*/fpm/pool.d/www.conf | grep -E "^pm\.|^pm " # For Docker (check inside container) docker exec your-wordpress-container cat /usr/local/etc/php-fpm.d/www.conf | grep -E "^pm\.|^pm " ``` Look for these values: ```ini pm = dynamic pm.max_children = 5 # ← This is usually the problem! pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 ``` ### Step 2: Calculate Optimal Worker Count **Formula:** ``` pm.max_children = (Available RAM) / (Average PHP Memory per Process) ``` **Example Calculations:** **2GB Server:** - Total RAM: 2048 MB - System RAM: ~512 MB - Available: 1536 MB - PHP Memory per Process: ~70 MB - **Recommended**: `pm.max_children = 20-25` **4GB Server:** - Total RAM: 4096 MB - System RAM: ~512 MB - Available: 3584 MB - PHP Memory per Process: ~70 MB - **Recommended**: `pm.max_children = 50` **8GB Server:** - Total RAM: 8192 MB - System RAM: ~512 MB - Available: 7680 MB - PHP Memory per Process: ~70 MB - **Recommended**: `pm.max_children = 100` ### Step 3: Apply Configuration **For Docker Deployments** (Recommended): Create `/opt/wordpress/php-fpm-custom.conf`: ```ini [www] pm = dynamic pm.max_children = 50 ; Adjust based on your RAM pm.start_servers = 10 ; Start with 10 workers pm.min_spare_servers = 5 ; Keep at least 5 idle pm.max_spare_servers = 20 ; Keep at most 20 idle pm.max_requests = 500 ; Recycle workers after 500 requests ; Logging for debugging pm.status_path = /status ping.path = /ping ping.response = pong ``` Mount it in `docker-compose.yml`: ```yaml wordpress: volumes: - ./php-fpm-custom.conf:/usr/local/etc/php-fpm.d/zz-custom.conf:ro ``` Restart: `docker compose restart wordpress` **For Standard PHP-FPM Installations**: ```bash # Edit PHP-FPM config (adjust PHP version as needed) sudo nano /etc/php/8.2/fpm/pool.d/www.conf # Find and modify: pm = dynamic pm.max_children = 50 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20 pm.max_requests = 500 # Restart PHP-FPM sudo systemctl restart php8.2-fpm # Verify sudo systemctl status php8.2-fpm ``` ### Step 4: Verify Changes ```bash # Check running PHP-FPM processes ps aux | grep php-fpm | wc -l # Should show 10+ processes initially # During load test, monitor scaling watch -n 1 "ps aux | grep php-fpm | wc -l" # Should scale up to match traffic ``` --- ## Additional Optimizations ### 1. Enable OpCache (PHP Bytecode Cache) OpCache compiles PHP code once and caches it, avoiding recompilation on every request. **Configuration** (`/etc/php/8.2/fpm/php.ini`): ```ini opcache.enable = 1 opcache.memory_consumption = 256 ; 256MB for cache opcache.max_accelerated_files = 20000 ; Cache up to 20k files opcache.validate_timestamps = 0 ; Don't check for file changes (production) opcache.revalidate_freq = 0 opcache.fast_shutdown = 1 ``` **Expected Impact**: 30-50% faster PHP execution ### 2. Optimize Nginx (if applicable) ```nginx worker_processes auto; # Use all CPU cores worker_connections 1024; # Handle 1024 connections per worker # Enable gzip compression gzip on; gzip_vary on; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; ``` ### 3. Increase MySQL Connections If you see "too many connections" errors: ```bash sudo nano /etc/mysql/my.cnf [mysqld] max_connections = 200 sudo systemctl restart mysql ``` ### 4. Monitor Resource Usage ```bash # CPU and memory usage htop # PHP-FPM status (if enabled) curl http://localhost/status?full # Disk I/O iostat -x 1 # Network usage iftop ``` --- ## Testing Your Optimization ### Before and After Comparison **Test Tool**: MaplePress CLI `wptest` command ```bash cd native/desktop/maplepress-cli # Run concurrent test (25 simultaneous requests) go run main.go wptest --url https://your-site.com --mode parallel --concurrency 25 ``` **Expected Results:** | Metric | Before | After (Optimized) | Improvement | |--------|--------|-------------------|-------------| | Average Response | 8,000ms | 300-500ms | **16-27x faster** | | P95 Latency | 9,000ms | < 1,000ms | **9x faster** | | Concurrent Handling | Queues 20/25 | Handles all 25 | **No queuing** | ### In-Plugin Speed Test Use the built-in **MaplePress → Speed Test** page in WordPress admin: 1. Go to **MaplePress** → **Speed Test** 2. Select number of trials (10-20 recommended) 3. Click **Run Speed Test** 4. Review results and recommendations --- ## Common Performance Issues ### Issue: High PHP Memory Usage **Symptoms**: - PHP workers crash with "out of memory" - WordPress shows white screen/500 errors **Solutions**: ```ini # Reduce worker count pm.max_children = 25 # Instead of 50 # Or increase PHP memory limit memory_limit = 256M # In php.ini ``` ### Issue: Still Slow After Optimization **Check**: 1. **Database queries**: Slow plugins, missing indexes ```bash # Enable MySQL slow query log slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1 ``` 2. **Caching**: Aggressive caching can hide PHP-FPM issues - Clear all caches and test - Disable page caching temporarily 3. **Network latency**: Test from different locations ```bash curl -w "@curl-format.txt" -o /dev/null -s https://your-site.com ``` 4. **Resource limits**: Check if hitting CPU/RAM limits ```bash # Monitor during load test top free -h ``` --- ## Production Deployment Checklist - [ ] PHP-FPM `pm.max_children` increased (≥ 25 for 2GB, ≥ 50 for 4GB) - [ ] OpCache enabled and configured - [ ] Nginx worker_processes set to `auto` - [ ] MySQL max_connections increased (≥ 200) - [ ] Caching strategy reviewed (not hiding problems) - [ ] Monitoring tools installed (htop, iotop, iftop) - [ ] Load testing performed (wptest with concurrency 25+) - [ ] Resource usage monitored under load - [ ] Backup/rollback plan in place --- ## Additional Resources ### WordPress Documentation - [PHP-FPM Configuration](https://www.php.net/manual/en/install.fpm.configuration.php) - [OpCache Configuration](https://www.php.net/manual/en/opcache.configuration.php) ### MaplePress Resources - **Production Deployment Guide**: See `cloud/infrastructure/production/setup/08_wordpress.md` in the MaplePress repository - **MaplePress CLI**: Speed testing and diagnostics tool - **Support**: Contact MaplePress support for optimization assistance ### Performance Tools - **htop**: Interactive process viewer - **iotop**: Disk I/O monitoring - **iftop**: Network bandwidth monitoring - **MySQL Tuner**: `mysqltuner.pl` for database optimization --- ## Summary **The #1 performance issue is PHP-FPM worker starvation, not backend speed.** MaplePress backend processes searches in < 20ms, but if your WordPress site only has 5 PHP-FPM workers and receives 25 concurrent requests, users will wait 8-10 seconds while requests queue. **Quick Win**: Increase `pm.max_children` from 5 to 50 (on 4GB server) for **16-27x faster response times**. Your MaplePress subscription includes a lightning-fast backend. Ensure your WordPress frontend can keep up! ⚡