# 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! ⚡
