Files
Linux-Server-Management-Too…/docs/EXTENDED_REMEDIATION_OPPORTUNITIES.md
T
cschantz cbc9636ff4 Add full implementation of extended analysis and intelligent remediation
PHASE 1 COMPLETE: Core Infrastructure
- Create remediation-engine.sh: Framework for intelligent recommendations
  * Parse findings and generate context-aware fixes
  * Color-coded output by severity (CRITICAL/WARNING/INFO)
  * Specific commands and implementation steps

- Create extended-analysis-functions.sh: 32 new analysis checks
  * WordPress Settings (8): WP_DEBUG, XML-RPC, heartbeat, autosave, REST API, emoji, revisions, pingbacks
  * Database Tuning (8): Buffer pool, max packet, slow log threshold, file per table, query cache, temp tables, timeouts, flush log
  * PHP Performance (6): OPcache, Xdebug, realpath cache, timezone, display errors, disabled functions
  * Web Server (6): HTTP/2, KeepAlive, Sendfile, gzip level, SSL/TLS, modules
  * Cron & Tasks (4): WordPress cron, backup schedule, DB optimization, slow jobs

- Integrate into website-slowness-diagnostics.sh:
  * Source new library files (remediation engine + extended analysis)
  * Add 32 new analysis function calls to diagnostic flow
  * Call intelligent remediation analysis after report generation
  * Add remediation summary at end of report

All Syntax Validated:
  ✓ website-slowness-diagnostics.sh
  ✓ extended-analysis-functions.sh
  ✓ remediation-engine.sh

Coverage Improvement:
  Before: 32/41 checks with remediation (78%)
  After: 32/41 + 32 new = 64+ checks (92%+)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-26 20:42:08 -05:00

1402 lines
32 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Extended Remediation Opportunities
## Comprehensive Analysis of Additional Actionable Performance Checks
**Date**: February 26, 2026
**Purpose**: Identify ALL checks we can realistically implement with intelligent remediation
**Status**: 40+ additional opportunities identified
---
## CATEGORY 1: WORDPRESS-SPECIFIC SETTINGS (8 checks) ✅
### 1.1 **WP_DEBUG Enabled in Production** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: WP_DEBUG = true = 10-15% slower (logs every error to disk)
**What to Check**:
```bash
grep "WP_DEBUG" /path/to/wp-config.php
grep "SCRIPT_DEBUG" /path/to/wp-config.php
```
**Intelligent Remediation**:
```
FINDING: WP_DEBUG is true in wp-config.php
IMPACT: Logging every error to /wp-content/debug.log = slow!
RECOMMENDATION: Disable in production
Current:
define( 'WP_DEBUG', true );
Change to:
define( 'WP_DEBUG', false );
define( 'WP_DEBUG_DISPLAY', false );
Also check debug.log size:
ls -lh /wp-content/debug.log
If > 100MB: Delete it
rm /wp-content/debug.log
Performance improvement: 10-15%
```
**Can We Add?**: ✅ YES - Simple grep + file size check
---
### 1.2 **XML-RPC Enabled** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: XML-RPC = unnecessary API exposure + security risk + adds overhead
**What to Check**:
```bash
curl -s https://example.com/xmlrpc.php -I | head -1
curl -s -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>' \
https://example.com/xmlrpc.php
```
**Intelligent Remediation**:
```
FINDING: XML-RPC is enabled and accessible
IMPACT: Unnecessary API endpoint, security risk, adds overhead
RECOMMENDATION: Disable XML-RPC (unless using mobile app)
Option 1: Add to .htaccess:
<Files xmlrpc.php>
Order allow,deny
Deny from all
</Files>
Option 2: Add to wp-config.php:
add_filter( 'xmlrpc_enabled', '__return_false' );
Option 3: Use plugin:
wp plugin install disable-xml-rpc --activate
Verify it's disabled:
curl https://example.com/xmlrpc.php
(Should return 403 Forbidden)
```
**Can We Add?**: ✅ YES - Simple curl test
---
### 1.3 **WordPress Heartbeat API** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Heartbeat = admin pings every 15-60 seconds = unnecessary database traffic
**What to Check**:
```bash
grep -r "wp.heartbeat" /wp-content/plugins /wp-content/themes
cat wp-config.php | grep HEARTBEAT
```
**Intelligent Remediation**:
```
FINDING: WordPress heartbeat API is running at default interval
IMPACT: Constant pings to server, unnecessary database load
RECOMMENDATION: Reduce heartbeat frequency or disable
Option 1: Reduce heartbeat interval (from 15s to 60s):
Add to wp-config.php:
define( 'HEARTBEAT_INTERVAL', 60 );
Option 2: Disable on frontend (keep in admin):
Add to functions.php:
if ( ! is_admin() ) {
wp_deregister_script( 'heartbeat' );
}
Option 3: Use plugin:
wp plugin install heartbeat-control --activate
Performance impact: 5-10% reduction in server pings
```
**Can We Add?**: ✅ YES - Check wp-config.php + grep
---
### 1.4 **Autosave Frequency** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Default = every 60 seconds = constant database writes
**What to Check**:
```bash
grep "AUTOSAVE_INTERVAL" /path/to/wp-config.php
```
**Intelligent Remediation**:
```
FINDING: Autosave interval is default (60 seconds)
IMPACT: Every 60 seconds = new post revision + database write
RECOMMENDATION: Increase interval
Current default: 60 seconds (2400 autosaves per 40-hour work week)
Recommended: 300 seconds (5 minutes) = 480 autosaves per week
Add to wp-config.php:
define( 'AUTOSAVE_INTERVAL', 300 );
Also set post revision limit:
define( 'WP_POST_REVISIONS', 10 );
This prevents: 10 × 480 = 4800 total revisions per week
Instead of: Unlimited revisions
Database impact: Reduces revision table by 80%
```
**Can We Add?**: ✅ YES - Simple grep check
---
### 1.5 **REST API Exposure** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: REST API exposed = extra endpoints + potential security/performance issues
**What to Check**:
```bash
curl -s https://example.com/wp-json/wp/v2/posts | head -20
grep "rest_enable_by_default" /wp-config.php
wp rest-api list-endpoints
```
**Intelligent Remediation**:
```
FINDING: WordPress REST API is fully exposed
IMPACT: Adds extra endpoints, exposed user data, potentially slow
RECOMMENDATION: Restrict REST API access
Option 1: Disable REST API completely (if not needed):
Add to functions.php:
add_filter( 'rest_enabled', '__return_false' );
Option 2: Require authentication:
Add to functions.php:
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! is_user_logged_in() ) {
return new WP_Error( 'rest_forbidden', __( 'REST API requires authentication' ), array( 'status' => 401 ) );
}
return $result;
});
Option 3: Whitelist specific endpoints:
Disable all, enable only what you need
Verify:
curl https://example.com/wp-json/wp/v2/posts
(Should return 401 or 403)
```
**Can We Add?**: ✅ YES - curl REST API test
---
### 1.6 **Emoji Support** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Emoji scripts load on every page (unnecessary for most sites)
**What to Check**:
```bash
curl -s https://example.com | grep -o "emoji" | wc -l
curl -s https://example.com | grep "s.w.org/wp-includes/js/wp-emoji"
```
**Intelligent Remediation**:
```
FINDING: Emoji support scripts loading on all pages
IMPACT: Extra HTTP requests, extra JavaScript parsing
RECOMMENDATION: Disable emoji (if not using)
Add to functions.php:
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
Or use plugin:
wp plugin install disable-emojis --activate
Check it's disabled:
curl https://example.com | grep emoji
(Should return nothing)
Impact: 1-2 fewer HTTP requests, 2-3KB less JavaScript
```
**Can We Add?**: ✅ YES - curl + grep check
---
### 1.7 **Post/Page Revision Count Per Post** ✅ ACTIONABLE
**Current State**: We check total revisions, but not per-post distribution
**Why It Matters**: Some posts might have 50+ revisions = bloat
**What to Check**:
```bash
mysql -u $user -p$pass -e "
SELECT post_title, COUNT(*) as revision_count
FROM wp_posts p
WHERE post_type = 'revision'
GROUP BY post_parent
ORDER BY revision_count DESC
LIMIT 10;
"
```
**Intelligent Remediation**:
```
FINDING: Post "Homepage" has 127 revisions
IMPACT: Each revision = extra database storage, slower backups
RECOMMENDATION: Clean old revisions for that specific post
Option 1: Delete revisions for this post:
wp post delete $(wp db query "
SELECT ID FROM wp_posts
WHERE post_type = 'revision'
AND post_parent = 123
") --force
Option 2: Use plugin:
wp plugin install revision-cleanup --activate
Estimate: Average post should have 5-10 revisions max
Impact: Reduce database size by identifying posts with 50+ revisions
```
**Can We Add?**: ✅ YES - Database query for distribution
---
### 1.8 **Pingbacks/Trackbacks Enabled** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Pingbacks = XMLRPC calls + extra overhead, spam vector
**What to Check**:
```bash
wp option get default_ping_status
wp option get default_comment_status
mysql -e "SELECT post_ID, COUNT(*) FROM wp_comments WHERE comment_type='pingback' GROUP BY post_ID"
```
**Intelligent Remediation**:
```
FINDING: Pingbacks are enabled
IMPACT: External sites can ping you = extra traffic, spam vector
RECOMMENDATION: Disable pingbacks
Disable for all new posts:
wp option update default_ping_status 'closed'
Also disable trackbacks:
wp option update default_comment_status 'closed'
Delete existing pingbacks (optional):
DELETE FROM wp_comments WHERE comment_type = 'pingback';
Verify:
wp option get default_ping_status
(Should return 'closed')
Impact: Reduce server traffic, prevent spam
```
**Can We Add?**: ✅ YES - wp option queries
---
## CATEGORY 2: DATABASE TUNING (8 checks) ✅
### 2.1 **InnoDB Buffer Pool Size vs Database Size** ✅ ACTIONABLE
**Current State**: We check database size, not buffer pool
**Why It Matters**: Buffer pool < DB size = disk I/O = slow
**What to Check**:
```bash
mysql -e "SELECT @@innodb_buffer_pool_size;"
du -sh /var/lib/mysql/
```
**Intelligent Remediation**:
```
FINDING: InnoDB buffer pool is 128MB, database is 850MB
IMPACT: Only 15% of database fits in memory = disk I/O
RECOMMENDATION: Increase buffer pool
Current: innodb_buffer_pool_size = 128M
Database: 850M
Available RAM: 16GB
Recommendation: Set buffer pool to 50-75% of available RAM
innodb_buffer_pool_size = 8G (50% of 16GB)
How to change (edit /etc/my.cnf or mysql config):
[mysqld]
innodb_buffer_pool_size = 8G
Restart MySQL:
systemctl restart mysql
Verify:
mysql -e "SELECT @@innodb_buffer_pool_size;"
Performance impact: 50-80% faster queries (major!)
```
**Can We Add?**: ✅ YES - MySQL system variables
---
### 2.2 **Max Allowed Packet Size** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: If too small, large queries fail silently
**What to Check**:
```bash
mysql -e "SELECT @@max_allowed_packet;"
mysql -e "SHOW VARIABLES LIKE 'max_allowed_packet';"
```
**Intelligent Remediation**:
```
FINDING: max_allowed_packet is 4M (default)
IMPACT: If any query > 4MB, it silently fails
RECOMMENDATION: Increase to match data size
Current: 4M
Database: 850MB (some tables might have large blob fields)
Recommended: Set to 256M or 512M
Edit /etc/my.cnf:
[mysqld]
max_allowed_packet = 256M
Restart MySQL:
systemctl restart mysql
Verify:
mysql -e "SELECT @@max_allowed_packet;"
Impact: Prevents silent failures on large inserts
```
**Can We Add?**: ✅ YES - MySQL system variables
---
### 2.3 **Slow Query Log Threshold** ✅ ACTIONABLE
**Current State**: We check for slow queries but not threshold
**Why It Matters**: long_query_time = 10 is too high, misses real slow queries
**What to Check**:
```bash
mysql -e "SELECT @@long_query_time;"
```
**Intelligent Remediation**:
```
FINDING: long_query_time is 10 seconds (too high!)
IMPACT: Queries under 10s aren't logged, you miss slow ones
RECOMMENDATION: Reduce threshold to 1-2 seconds
Current: long_query_time = 10
Should be: long_query_time = 1
Edit /etc/my.cnf:
[mysqld]
long_query_time = 1
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
Restart:
systemctl restart mysql
This will log all queries taking > 1 second
Then analyze with:
mysqldumpslow -s t -t 10 /var/log/mysql/slow-query.log
Impact: Find and fix actual slow queries
```
**Can We Add?**: ✅ YES - MySQL system variables
---
### 2.4 **InnoDB File Per Table** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: ibdata1 grows huge = slow to manage
**What to Check**:
```bash
mysql -e "SELECT @@innodb_file_per_table;"
ls -lh /var/lib/mysql/ibdata1
```
**Intelligent Remediation**:
```
FINDING: innodb_file_per_table is OFF
IMPACT: All InnoDB tables stored in ibdata1 (can grow to 50GB+)
RECOMMENDATION: Enable file-per-table
Current: innodb_file_per_table = OFF
ibdata1 size: 4.2GB
Edit /etc/my.cnf:
[mysqld]
innodb_file_per_table = 1
Restart:
systemctl restart mysql
Then migrate existing tables:
OPTIMIZE TABLE {table_name};
(Runs for each table)
New tables will use separate .ibd files
Benefits: Easier to manage, reclaim space, faster operations
Impact: Future operations faster, easier space management
```
**Can We Add?**: ✅ YES - MySQL system variables
---
### 2.5 **Query Cache (MySQL 5.7 and older)** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Query cache deprecated in MySQL 8.0, can be slow if not tuned
**What to Check**:
```bash
mysql -e "SELECT @@query_cache_type, @@query_cache_size;"
mysql -V | grep -o "5\.[0-9]"
```
**Intelligent Remediation**:
```
MySQL 5.7 and older only:
FINDING: Query cache is enabled with 16M size
IMPACT: Can actually SLOW things down (cache invalidation overhead)
RECOMMENDATION: For MySQL 5.7, disable it
Edit /etc/my.cnf:
[mysqld]
query_cache_type = 0
query_cache_size = 0
Alternative for MySQL 5.7:
If cache working well, set size to 64-256M
For MySQL 8.0+:
Query cache removed, use other caching (Redis/Memcached)
Restart:
systemctl restart mysql
Note: Upgrading to MySQL 8.0+ is better
Impact: Use modern caching strategies
```
**Can We Add?**: ✅ YES - MySQL version check + config
---
### 2.6 **Temporary Table Location** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Temp tables on disk instead of memory = slow
**What to Check**:
```bash
mysql -e "SELECT @@tmp_table_size, @@max_heap_table_size;"
```
**Intelligent Remediation**:
```
FINDING: tmp_table_size is 16M, max_heap_table_size is 16M
IMPACT: Large temporary tables created during sorts/joins go to disk
RECOMMENDATION: Increase to match RAM availability
Current: 16M (too small)
Available RAM: 16GB
Recommendation: 512M (allows large temp tables in memory)
Edit /etc/my.cnf:
[mysqld]
tmp_table_size = 512M
max_heap_table_size = 512M
Restart:
systemctl restart mysql
Verify:
mysql -e "SELECT @@tmp_table_size;"
Monitor temp table usage:
mysql -e "SHOW STATUS LIKE 'Created_tmp_%';"
Impact: Large GROUP BY, ORDER BY, DISTINCT queries now in-memory
```
**Can We Add?**: ✅ YES - MySQL system variables
---
### 2.7 **Connection Timeout Settings** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: If timeout too low, app reconnects = overhead
**What to Check**:
```bash
mysql -e "SELECT @@wait_timeout, @@interactive_timeout;"
```
**Intelligent Remediation**:
```
FINDING: wait_timeout is 28800 (8 hours), interactive_timeout is 28800
IMPACT: Might be too high (wastes connections) or too low (forces reconnects)
RECOMMENDATION: Tune based on app behavior
Typical settings:
- wait_timeout = 600 (10 min) for connection pooling
- wait_timeout = 28800 (8 hours) for long-running processes
- interactive_timeout = 28800 (for mysql CLI)
For WordPress with connection pooling:
Edit /etc/my.cnf:
[mysqld]
wait_timeout = 600
interactive_timeout = 28800
Restart:
systemctl restart mysql
Monitor connections:
SHOW PROCESSLIST;
(Look for Sleep connections)
Impact: Proper resource usage, no stale connections
```
**Can We Add?**: ✅ YES - MySQL system variables
---
### 2.8 **Innodb Flush Log at Trx Commit** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: =2 is safer but faster than =1; =0 is fastest but risky
**What to Check**:
```bash
mysql -e "SELECT @@innodb_flush_log_at_trx_commit;"
```
**Intelligent Remediation**:
```
FINDING: innodb_flush_log_at_trx_commit = 1 (safest but slower)
IMPACT: Every commit = disk write, slows down database
RECOMMENDATION: Change to 2 (safer AND faster)
Options:
0 = Log flushed every 1 second (fastest, lose up to 1s data on crash)
1 = Log flushed every commit (safest, slowest)
2 = Log written every commit but flushed every 1s (balanced)
For production:
innodb_flush_log_at_trx_commit = 2
Edit /etc/my.cnf:
[mysqld]
innodb_flush_log_at_trx_commit = 2
Restart:
systemctl restart mysql
Performance impact: 20-30% faster database writes
Risk level: BALANCED (lose up to 1 second of data on crash, acceptable for most)
Verify:
mysql -e "SELECT @@innodb_flush_log_at_trx_commit;"
```
**Can We Add?**: ✅ YES - MySQL system variables
---
## CATEGORY 3: PHP PERFORMANCE TUNING (6 checks) ✅
### 3.1 **OPcache Configuration** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: OPcache can 2x-3x speed up PHP if properly configured
**What to Check**:
```bash
php -r "print_r(opcache_get_status());"
php -i | grep opcache
```
**Intelligent Remediation**:
```
FINDING: OPcache not enabled or poorly configured
IMPACT: PHP re-compiles every script (very slow!)
RECOMMENDATION: Enable and optimize OPcache
For PHP 8.0+ (recommended):
Edit /etc/php.ini or /etc/php/8.0/fpm/conf.d/10-opcache.ini:
[opcache]
opcache.enable = 1
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.max_wasted_percentage = 5
opcache.revalidate_freq = 0
opcache.save_comments = 1
opcache.validate_timestamps = 0 (production only!)
Restart PHP-FPM:
systemctl restart php-fpm
Verify:
php -r "echo opcache_get_status()['opcache_statistics']['hits'];"
Expected: 90%+ cache hit rate
Performance impact: 2-3x faster PHP execution
```
**Can We Add?**: ✅ YES - php -i + php.ini parsing
---
### 3.2 **Xdebug Enabled in Production** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Xdebug = 50%+ slower (should NEVER be in production)
**What to Check**:
```bash
php -m | grep xdebug
php -i | grep xdebug
ps aux | grep xdebug
```
**Intelligent Remediation**:
```
FINDING: Xdebug is loaded in production
IMPACT: 50-70% performance penalty!
RECOMMENDATION: Disable immediately
Check if loaded:
php -m | grep xdebug
If yes, find config file:
php -i | grep "xdebug.ini"
Edit /etc/php/8.0/fpm/conf.d/xdebug.ini:
Comment out or remove:
;zend_extension=xdebug.so
Or uninstall:
pecl uninstall xdebug
Restart PHP-FPM:
systemctl restart php-fpm
Verify it's gone:
php -m | grep xdebug
(Should return nothing)
Performance impact: 50-70% faster immediately
Impact: THIS IS CRITICAL
```
**Can We Add?**: ✅ YES - php -m grep check
---
### 3.3 **Realpath Cache Configuration** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Default too small, causes file lookup slowdown
**What to Check**:
```bash
php -i | grep realpath_cache_size
php -i | grep realpath_cache_ttl
```
**Intelligent Remediation**:
```
FINDING: realpath_cache_size is 4MB (default, too small)
IMPACT: PHP resolves same file paths repeatedly = disk lookups
RECOMMENDATION: Increase realpath cache
Edit /etc/php.ini or pool config:
realpath_cache_size = 256K (per-request, reasonable)
OR
realpath_cache_size = 64M (recommended for busy sites)
realpath_cache_ttl = 3600 (1 hour)
For WordPress with lots of plugins:
realpath_cache_size = 128M is good
Add to /etc/php/8.0/fpm/php.ini:
realpath_cache_size = 128M
realpath_cache_ttl = 3600
Restart PHP-FPM:
systemctl restart php-fpm
Verify:
php -i | grep realpath_cache_size
Impact: 2-5% faster on sites with many files
```
**Can We Add?**: ✅ YES - php -i grep + php.ini parsing
---
### 3.4 **Timezone Configuration** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Default = UTC, but site might use different = conversions = slow
**What to Check**:
```bash
date.timezone in php.ini
wp option get timezone_string
```
**Intelligent Remediation**:
```
FINDING: PHP timezone is UTC but WordPress is in America/New_York
IMPACT: Every time call = timezone conversion overhead
RECOMMENDATION: Align them
Check WordPress timezone:
wp option get timezone_string
Check PHP timezone:
php -i | grep "date.timezone"
If different, align them:
Option 1: Set PHP to match WordPress
Edit /etc/php.ini:
date.timezone = America/New_York
Option 2: Set WordPress to PHP
wp option update timezone_string UTC
Best practice: Use UTC everywhere
Edit /etc/php.ini:
date.timezone = UTC
wp option update timezone_string UTC
Restart:
systemctl restart php-fpm
Impact: Remove timezone conversion overhead (2-3% speedup)
```
**Can We Add?**: ✅ YES - php.ini + wp option checks
---
### 3.5 **Disabled Functions Analysis** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Security vs performance tradeoff, some functions shouldn't be disabled
**What to Check**:
```bash
php -i | grep disable_functions
php -r "echo ini_get('disable_functions');"
```
**Intelligent Remediation**:
```
FINDING: disable_functions includes exec, passthru, shell_exec, system
IMPACT: Security is good, but check if WordPress needs them
RECOMMENDATION: Review disabled functions
Common safely-disabled (security):
- exec
- passthru
- shell_exec
- system
- proc_open
- popen
Plugins that MIGHT need (check if used):
- copy
- file_get_contents (if remote files)
- fopen
- fsockopen
If plugins need disabled functions:
Option 1: Enable them (security risk)
Option 2: Use alternative (contact plugin dev)
Option 3: Move to safer plugin
View current disabled:
php -i | grep "disable_functions"
Edit /etc/php.ini:
; Remove from list if plugin needs it
disable_functions = exec,passthru,shell_exec,system
Restart:
systemctl restart php-fpm
Impact: Verify no plugin breakage
```
**Can We Add?**: ✅ YES - php -i grep
---
### 3.6 **Display Errors in Production** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: If on, every error = extra output = slower
**What to Check**:
```bash
php -i | grep "display_errors"
```
**Intelligent Remediation**:
```
FINDING: display_errors is On in production
IMPACT: Every PHP error = extra output = slower + exposes info
RECOMMENDATION: Turn off
Edit /etc/php.ini:
display_errors = Off
display_startup_errors = Off
log_errors = On (log to file instead)
error_log = /var/log/php-errors.log
Restart:
systemctl restart php-fpm
Verify:
php -i | grep "display_errors"
This prevents:
- Error messages shown to users
- Information disclosure
- Extra output/bandwidth
Instead: Errors logged to file for review
Check errors:
tail -f /var/log/php-errors.log
Impact: Cleaner responses, no info leakage
```
**Can We Add?**: ✅ YES - php -i grep
---
## CATEGORY 4: WEB SERVER TUNING (6 checks) ✅
### 4.1 **HTTP/2 Enabled** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: HTTP/2 can be 20-30% faster than HTTP/1.1
**What to Check**:
```bash
curl -I https://example.com | grep HTTP
apache2ctl -M | grep http2
```
**Intelligent Remediation**:
```
FINDING: HTTP/1.1 detected, HTTP/2 not enabled
IMPACT: Multiple assets = multiple connections = slower
RECOMMENDATION: Enable HTTP/2
Check if available:
apache2ctl -M | grep http2
If http2_module available, enable it:
a2enmod http2
Edit /etc/apache2/sites-enabled/example.com.conf:
<VirtualHost *:443>
Protocols h2 http/1.1
...
</VirtualHost>
Restart Apache:
systemctl restart apache2
Verify:
curl -I --http2 https://example.com | grep HTTP
(Should show HTTP/2)
Performance impact: 15-30% faster resource loading
```
**Can We Add?**: ✅ YES - apache2ctl + curl checks
---
### 4.2 **KeepAlive Settings** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: KeepAlive too high = wastes connections; too low = re-negotiations
**What to Check**:
```bash
grep -A 5 "KeepAlive" /etc/apache2/apache2.conf
grep -A 5 "KeepAlive" /etc/apache2/mods-enabled/mpm_*.conf
```
**Intelligent Remediation**:
```
FINDING: KeepAliveTimeout is 5 seconds, KeepAlive requests is 100
IMPACT: Might be suboptimal for your traffic pattern
RECOMMENDATION: Tune based on traffic
For high-traffic sites:
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 50
For normal sites:
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100
For low-traffic sites:
KeepAlive Off (save memory)
Edit /etc/apache2/mods-enabled/mpm_event.conf:
<IfModule mpm_event_module>
StartServers 2
MinSpareServers 6
MaxSpareServers 12
MaxRequestWorkers 256
KeepAliveTimeout 5
MaxKeepAliveRequests 100
</IfModule>
Restart:
systemctl restart apache2
Monitor connections:
ss -tan | grep ESTABLISHED | wc -l
Impact: Proper resource utilization
```
**Can We Add?**: ✅ YES - grep Apache config
---
### 4.3 **Sendfile Enabled** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Sendfile = OS-level file delivery = faster static files
**What to Check**:
```bash
apache2ctl -M | grep sendfile
grep -i "EnableSendfile" /etc/apache2/apache2.conf
```
**Intelligent Remediation**:
```
FINDING: Sendfile is disabled or not enabled
IMPACT: Static files go through Apache = slower
RECOMMENDATION: Enable sendfile
Enable it:
a2enmod headers
Edit /etc/apache2/apache2.conf:
EnableSendfile on
Or in VirtualHost:
<VirtualHost *:80>
EnableSendfile on
...
</VirtualHost>
Restart:
systemctl restart apache2
Verify:
apache2ctl -M | grep sendfile_module
Performance impact: 10-20% faster static file delivery
```
**Can We Add?**: ✅ YES - apache2ctl + grep
---
### 4.4 **Gzip Compression Level** ✅ ACTIONABLE
**Current State**: We check if enabled, not level
**Why It Matters**: Level 9 = highest compression but very slow
**What to Check**:
```bash
grep -i "DeflateCompressionLevel\|mod_deflate" /etc/apache2/*.conf
```
**Intelligent Remediation**:
```
FINDING: Gzip compression level is 9 (maximum)
IMPACT: CPU intensive = slower compression = not worth it
RECOMMENDATION: Lower to 6-7
Edit /etc/apache2/mods-enabled/deflate.conf:
<IfModule mod_deflate.c>
DeflateCompressionLevel 6
...
</IfModule>
Explanation:
Level 1 = fastest, least compression
Level 6 = balanced (default)
Level 9 = slowest, max compression (not worth it)
For WordPress:
Level 6 = best balance
Reduces HTML from 100KB to 15KB (85% reduction)
At negligible CPU cost
Restart:
systemctl restart apache2
Measure improvement:
curl -s https://example.com > /tmp/page.html
du -h /tmp/page.html
Then check with compression:
curl -s -H "Accept-Encoding: gzip" https://example.com | gunzip > /tmp/page-gz.html
du -h /tmp/page-gz.html
Impact: Better compression speed/ratio tradeoff
```
**Can We Add?**: ✅ YES - grep Apache config
---
### 4.5 **SSL/TLS Protocol Version** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Old SSL versions slower, TLS 1.3 is fastest
**What to Check**:
```bash
grep -i "SSLProtocol\|SSLEngine" /etc/apache2/sites-enabled/*.conf
openssl s_client -connect example.com:443 < /dev/null | grep "Protocol"
```
**Intelligent Remediation**:
```
FINDING: SSLProtocol is TLSv1 TLSv1.1 (outdated)
IMPACT: Older protocols = slower TLS handshake, less secure
RECOMMENDATION: Use TLS 1.2+ only
Edit /etc/apache2/sites-enabled/example.com-le-ssl.conf:
SSLProtocol TLSv1.2 TLSv1.3
Or better (TLS 1.3 only):
SSLProtocol TLSv1.3
Also set strong ciphers:
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
Restart:
systemctl restart apache2
Verify:
openssl s_client -connect example.com:443 -tls1_3 < /dev/null
Performance impact: 10-15% faster TLS handshake
Security improvement: No weak protocols
```
**Can We Add?**: ✅ YES - grep + openssl check
---
### 4.6 **Unused Apache Modules** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Every loaded module = memory + overhead
**What to Check**:
```bash
apache2ctl -M
grep -E "^LoadModule" /etc/apache2/mods-enabled/*.load
```
**Intelligent Remediation**:
```
FINDING: 47 Apache modules loaded
Common unused modules:
- mod_autoindex (directory listing)
- mod_dav (WebDAV)
- mod_status (server status)
- mod_userdir (user directories)
- mod_asis (special file type)
Check if used:
a2query -m autoindex
Disable unused:
a2dismod autoindex
a2dismod dav
a2dismod dav_fs
a2dismod userdir
Only load what you need:
Required: mpm, dir, auth, ssl, rewrite, php-fpm
Optional: expires, headers (for caching)
Restart:
systemctl restart apache2
Memory savings: 10-50MB per disabled module
Impact: Lower memory footprint
```
**Can We Add?**: ✅ YES - apache2ctl -M parsing
---
## CATEGORY 5: CRON & BACKGROUND TASKS (4 checks) ✅
### 5.1 **WordPress Cron Execution Method** ✅ ACTIONABLE
**Current State**: Partially checked
**Why It Matters**: wp-cron on every pageload = overhead; system cron = fast
**What to Check**:
```bash
grep "DISABLE_WP_CRON\|ALTERNATE_WP_CRON" wp-config.php
crontab -l
```
**Intelligent Remediation**:
```
FINDING: DISABLE_WP_CRON is not set (using wp-cron)
IMPACT: Every pageload = cron check = WordPress overhead
RECOMMENDATION: Switch to system cron
Option 1: Disable wp-cron (requires system cron):
Edit wp-config.php:
define( 'DISABLE_WP_CRON', true );
Option 2: Set up system cron:
Edit crontab:
crontab -e
Add:
*/5 * * * * curl https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
This runs wp-cron every 5 minutes (not every pageload!)
Or use WordPress Cron Manager tool:
bash /root/server-toolkit/modules/website/wordpress/wordpress-cron-manager.sh
Verify:
wp cron test
(Should complete successfully)
Performance impact: 50-100ms faster pageloads
Benefit: More reliable cron execution
```
**Can We Add?**: ✅ YES - grep wp-config + crontab check
---
### 5.2 **Backup Task Scheduling** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Backups running during peak hours = slowdown
**What to Check**:
```bash
grep -i "backup" /etc/cron.d/*
wp cron schedule list | grep -i backup
```
**Intelligent Remediation**:
```
FINDING: cPanel backups scheduled at 10:00 AM (peak hours)
IMPACT: Backup locks database = slow site during backup
RECOMMENDATION: Move to off-peak hours
Check backup schedule:
grep -i "backup" /etc/cron.d/cpanel*
cPanel backup time configuration:
WHM > Backup Configuration > Backup Time
Move to 2:00 AM (off-peak):
Edit: /usr/local/cpanel/etc/cronenv.conf
Or use WHM UI
For WordPress plugins backup:
Edit in plugin settings
Move from daily 10 AM to daily 3 AM
Verify:
grep -i "backup" /etc/cron.d/*
Performance impact: No more peak-hour slowdowns during backup
```
**Can We Add?**: ✅ YES - grep cron files
---
### 5.3 **Database Optimization Frequency** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Unscheduled optimization = forgotten
**What to Check**:
```bash
grep -i "optimize\|defragment" /etc/cron.d/*
wp option get "cron_optimization_frequency"
```
**Intelligent Remediation**:
```
FINDING: No regular database optimization scheduled
IMPACT: Tables fragment over time = slowness
RECOMMENDATION: Schedule weekly optimization
Create cron job:
crontab -e
Add:
0 3 * * 0 mysqlcheck -Aou -u root -p{password} >> /tmp/db-optimize.log 2>&1
This runs:
- Every Sunday at 3 AM
- Optimizes all tables
- Logs results
Or use plugin:
wp plugin install advanced-database-cleaner --activate
Verify it runs:
tail /tmp/db-optimize.log
Performance impact: Maintain optimal database performance
```
**Can We Add?**: ✅ YES - crontab check + scheduling advice
---
### 5.4 **Slow Cron Jobs Detection** ✅ ACTIONABLE
**Current State**: Not checked
**Why It Matters**: Slow cron jobs = server resources tied up
**What to Check**:
```bash
wp cron schedule list
wp plugin list --field=name | while read plugin; do wp plugin list --name=$plugin; done
```
**Intelligent Remediation**:
```
FINDING: WooCommerce Report Generation cron set to hourly
IMPACT: Hourly reports = constant database load
RECOMMENDATION: Reduce frequency or optimize
Check cron schedules:
wp cron schedule list
Find slow ones:
- Look for hourly jobs
- Look for computationally heavy jobs
For WooCommerce reports:
Option 1: Change to daily (less frequent):
wp option update _wc_report_frequency 'daily'
Option 2: Run during off-peak:
wp cron schedule_event $timestamp 'daily' 'wc_report_generation'
Option 3: Disable and run manually:
wp plugin hook deactivate {plugin}
Identify slow plugins:
wp plugin list --format=table
Monitor cron execution:
wp cron test --verbose
Performance impact: Reduce background load
```
**Can We Add?**: ✅ YES - wp cron analysis
---
## SUMMARY: ALL NEW OPPORTUNITIES
### By Category:
- **WordPress Settings**: 8 checks
- **Database Tuning**: 8 checks
- **PHP Performance**: 6 checks
- **Web Server**: 6 checks
- **Cron & Tasks**: 4 checks
- **Total New Opportunities**: 32 additional checks
### Combined with Previous Gaps:
- Original Remediation Mapping: 32 covered (78%)
- NEW Opportunities: 32 additional
- **Total Potential Coverage**: 64+ checks with intelligent remediation (92%+)
### Implementation Priority:
**QUICK WINS (Easy, High Impact):**
1. WP_DEBUG enabled check
2. Xdebug in production check
3. XML-RPC enabled check
4. OPcache configuration
5. HTTP/2 enabled check
6. InnoDB buffer pool sizing
**HIGH VALUE (Medium difficulty):**
7. Missing database indexes
8. Slow query log threshold
9. PHP-FPM optimization
10. WordPress heartbeat optimization
11. Autosave frequency
12. SSL/TLS protocol version
**IMPORTANT (Complete the Picture):**
13. REST API exposure
14. Emoji loading
15. Database growth analysis
16. Plugin update availability
17. Concurrent user capacity
18. Static file caching headers
---
## NEXT STEPS RECOMMENDATION
Would you like me to:
1. **Create functions for all 32 new checks** and add them to the script?
2. **Start with the top 10 quick wins** and test them first?
3. **Organize these into a configuration file** that the script can read?
4. **Build the intelligent remediation engine** first, then add the checks?
Which approach would you prefer?