What's Actually Happening

You deployed new PHP code to your server, but users are still seeing the old version. Changes to your PHP files aren't reflected - you modified a class, changed a function, or updated a configuration file, but the application behaves as if nothing changed. The OPCache is serving stale compiled scripts from its cache, ignoring the updated files on disk.

OPCache improves PHP performance by compiling PHP scripts once and storing the compiled bytecode in shared memory. When this cache isn't properly invalidated after deployments, your application continues running old code, causing bugs, missing features, and confusion.

The Error You'll See

PHP OPCache issues manifest in several ways:

```bash # Code changes not reflected # Old function still being called Fatal error: Call to undefined function App\newFunction()

# Class changes not applied # Still calling old method signature TypeError: Too few arguments to function MyClass::oldMethod()

# Configuration changes ignored # Old config values still in use

# View/Template changes not showing # Frontend still rendering old HTML

# OPCache status showing stale files $ php -r "print_r(opcache_get_status());" Array ( [opcache_enabled] => 1 [cache_full] => [restart_pending] => [restart_in_progress] => [memory_usage] => Array(...) [interned_strings_usage] => Array(...) [opcache_statistics] => Array ( [num_cached_scripts] => 156 [num_cached_keys] => 156 [max_cached_keys] => 16229 [hits] => 45678 [misses] => 156 [blacklist_miss_ratio] => 0 [blacklist_misses] => 0 [opcache_hit_rate] => 99.66 ) [cached_scripts] => Array ( [0] => Array ( [full_path] => /var/www/app/src/OldClass.php [hits] => 1234 [memory_consumption] => 45678 [last_used_timestamp] => 1712654400 # Old timestamp! ) ) )

# Reset returns false $ php -r "var_dump(opcache_reset());" bool(false)

# Or resets but code still old $ php -r "opcache_reset();" && php -r "echo 'Done';" Done # But old code still executing!

# In web server error log [error] PHP Fatal error: Declaration of App\\NewClass::method() must be compatible with App\\OldClass::method()

# APCu user cache also stale $ php -r "apcu_clear_cache();" # But items still cached

# File timestamp shows old file $ ls -la src/MyClass.php -rw-r--r-- 1 www-data www-data 1234 Apr 9 10:00 src/MyClass.php

# But new file deployed $ stat src/MyClass.php File: src/MyClass.php Modify: 2026-04-09 09:30:00.000000000 +0000 ```

Additional symptoms: - Changes visible in source files but not executed - Some pages updated, others still old - Clearing browser cache doesn't help - Works in development but not production - Intermittent old/new code mixing - opcache_reset() returns false or doesn't work - Random scripts showing old versions - Deployment scripts don't clear cache properly

Why This Happens

  1. 1.OPCache Invalidation Disabled: opcache.validate_timestamps is set to 0 (disabled), so OPCache never checks if files changed on disk. It continues serving cached bytecode indefinitely.
  2. 2.Long Revalidate Frequency: opcache.revalidate_freq is set too high (e.g., 60 seconds). OPCache only checks file timestamps every N seconds, causing delay in seeing changes.
  3. 3.PHP-FPM Process Pool: Multiple PHP-FPM workers have their own OPCache. Resetting from one worker doesn't clear other workers' caches. Each process maintains its own cached scripts.
  4. 4.CLI vs FPM Different Processes: Running php -r "opcache_reset();" from CLI doesn't affect PHP-FPM's OPCache because they're separate processes with separate caches.
  5. 5.Permission Issues: The web server user doesn't have permission to reset OPCache, or the reset function is disabled in PHP configuration.
  6. 6.OPCache Locked: OPCache is busy or locked during reset operation, preventing the reset from completing.
  7. 7.Cached Scripts Path Mismatch: The cached scripts use different paths (absolute vs relative, symlinks) than the new files, causing OPCache to keep old entries.
  8. 8.Enable/Disable Race Condition: During deployment, some requests hit the new code while OPCache still has old compiled scripts cached.

Step 1: Check OPCache Configuration

Examine current OPCache settings.

```bash # Check OPCache is enabled php -i | grep opcache

# Or via web: echo "<?php phpinfo(); ?>" > /var/www/html/info.php # Visit http://your-site/info.php

# Check specific settings php -i | grep "opcache.enable" php -i | grep "opcache.validate_timestamps" php -i | grep "opcache.revalidate_freq" php -i | grep "opcache.memory_consumption" php -i | grep "opcache.interned_strings_buffer" php -i | grep "opcache.max_accelerated_files" php -i | grep "opcache.max_wasted_percentage" php -i | grep "opcache.use_cwd" php -i | grep "opcache.enable_cli" php -i | grep "opcache.save_comments" php -i | grep "opcache.fast_shutdown"

# Get full OPCache status php -r " \$status = opcache_get_status(); if (\$status) { echo 'OPCache Enabled: ' . (\$status['opcache_enabled'] ? 'Yes' : 'No') . PHP_EOL; echo 'Memory Used: ' . round(\$status['memory_usage']['used_memory'] / 1024 / 1024, 2) . ' MB' . PHP_EOL; echo 'Memory Free: ' . round(\$status['memory_usage']['free_memory'] / 1024 / 1024, 2) . ' MB' . PHP_EOL; echo 'Cached Scripts: ' . \$status['opcache_statistics']['num_cached_scripts'] . PHP_EOL; echo 'Hit Rate: ' . round(\$status['opcache_statistics']['opcache_hit_rate'], 2) . '%' . PHP_EOL; } "

# Find php.ini location php --ini

# Check OPCache configuration file cat /etc/php/8.2/fpm/conf.d/10-opcache.ini cat /etc/php/8.2/mods-available/opcache.ini

# Check if OPCache is configured in php.ini grep opcache /etc/php/8.2/fpm/php.ini

# Check for configuration overrides ls -la /etc/php/8.2/fpm/conf.d/ | grep opcache ```

Step 2: Enable Timestamp Validation

Configure OPCache to check for file changes.

```bash # Edit OPCache configuration: sudo nano /etc/php/8.2/fpm/conf.d/10-opcache.ini

# Add or modify these settings: ```

```ini ; Enable OPCache opcache.enable=1

; Enable CLI OPCache (optional, for testing) opcache.enable_cli=1

; Check file timestamps for changes opcache.validate_timestamps=1

; How often to check timestamps (seconds) ; 0 = check every request (development) ; 1-60 = check every N seconds (production) opcache.revalidate_freq=0

; Memory for cached scripts opcache.memory_consumption=256

; Memory for interned strings opcache.interned_strings_buffer=16

; Maximum cached files opcache.max_accelerated_files=10000

; Max wasted memory before restart opcache.max_wasted_percentage=10

; Use current working directory opcache.use_cwd=1

; Save comments (for annotations) opcache.save_comments=1

; Fast shutdown opcache.fast_shutdown=1

; Enable file override opcache.override_lru_sort=1

; Inotify for instant invalidation (Linux only) opcache.inotify_enable=1

; Blacklist files from caching opcache.blacklist_filename=/etc/php/8.2/fpm/opcache-blacklist.txt ```

```bash # Create blacklist file if needed sudo touch /etc/php/8.2/fpm/opcache-blacklist.txt

# Restart PHP-FPM sudo systemctl restart php8.2-fpm

# Verify settings applied php -i | grep opcache.validate_timestamps php -i | grep opcache.revalidate_freq ```

Step 3: Clear OPCache Properly

Reset OPCache through the correct method.

```bash # Method 1: Via PHP file (for web) cat > /var/www/html/clear-opcache.php << 'EOF' <?php if (function_exists('opcache_reset')) { if (opcache_reset()) { echo "OPCache cleared successfully\n"; } else { echo "OPCache reset failed\n"; } } else { echo "OPCache not available\n"; }

if (function_exists('apcu_clear_cache')) { apcu_clear_cache(); echo "APCu cache cleared\n"; }

// Show status after reset $status = opcache_get_status(false); echo "\nCached scripts: " . $status['opcache_statistics']['num_cached_scripts'] . "\n"; echo "Hit rate: " . round($status['opcache_statistics']['opcache_hit_rate'], 2) . "%\n"; EOF

# Access via web: curl http://localhost/clear-opcache.php

# Method 2: Via PHP-FPM reload sudo systemctl reload php8.2-fpm

# Method 3: Full PHP-FPM restart sudo systemctl restart php8.2-fpm

# Method 4: Via FPM status page (if enabled) curl http://localhost/php-fpm-status

# Method 5: Clear all PHP-FPM pools for pool in /etc/php/8.2/fpm/pool.d/*.conf; do pool_name=$(basename "$pool" .conf) echo "Restarting pool: $pool_name" done sudo systemctl restart php8.2-fpm

# Method 6: Use opcache_invalidate for specific file php -r " if (function_exists('opcache_invalidate')) { opcache_invalidate('/var/www/app/src/MyClass.php', true); echo 'File invalidated\n'; } "

# Method 7: Clear via script with multiple methods cat > /var/www/html/opcache-clear-all.php << 'EOF' <?php header('Content-Type: text/plain');

echo "=== Clearing OPCache ===\n\n";

// Method 1: Full reset if (function_exists('opcache_reset')) { $result = opcache_reset(); echo "opcache_reset(): " . ($result ? "SUCCESS" : "FAILED") . "\n"; }

// Method 2: Force invalidate all cached scripts if (function_exists('opcache_get_status')) { $status = opcache_get_status(); if (isset($status['scripts'])) { foreach (array_keys($status['scripts']) as $file) { if (function_exists('opcache_invalidate')) { opcache_invalidate($file, true); } } echo "Invalidated " . count($status['scripts']) . " scripts\n"; } }

// Clear APCu if present if (function_exists('apcu_clear_cache')) { apcu_clear_cache(); echo "APCu cleared\n"; }

// Show final status $status = opcache_get_status(false); echo "\n=== Final Status ===\n"; echo "OPCache Enabled: " . ($status['opcache_enabled'] ? 'Yes' : 'No') . "\n"; echo "Cached Scripts: " . $status['opcache_statistics']['num_cached_scripts'] . "\n"; echo "Memory Used: " . round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . " MB\n"; EOF

curl http://localhost/opcache-clear-all.php ```

Step 4: Configure Deployment Cache Clear

Add automatic cache clearing to your deployment process.

bash
# For Laravel deployments
# In your deployment script:

```bash #!/bin/bash # Laravel deployment with OPCache clear

APP_DIR="/var/www/laravel"

cd $APP_DIR

# Pull latest code git pull origin main

# Install dependencies composer install --no-dev --optimize-autoloader

# Run migrations php artisan migrate --force

# Clear Laravel caches php artisan cache:clear php artisan config:clear php artisan route:clear php artisan view:clear

# Clear OPCache via PHP-FPM reload sudo systemctl reload php8.2-fpm

# Or clear via web endpoint curl -s http://localhost/opcache-clear-all.php

# Optimize for production php artisan config:cache php artisan route:cache php artisan view:cache

echo "Deployment complete!" ```

```bash # For Symfony deployments cat > deploy.sh << 'EOF' #!/bin/bash

APP_DIR="/var/www/symfony"

cd $APP_DIR

# Update code git pull

# Install dependencies composer install --no-dev --optimize-autoloader

# Clear Symfony cache php bin/console cache:clear --env=prod

# Warm up cache php bin/console cache:warmup --env=prod

# Clear OPCache sudo systemctl reload php8.2-fpm

# Or via script php bin/console cache:pool:clear cache.global_clearer

echo "Symfony deployment complete" EOF

chmod +x deploy.sh ```

```bash # For WordPress deployments cat > wp-deploy.sh << 'EOF' #!/bin/bash

WP_DIR="/var/www/wordpress"

cd $WP_DIR

# Update files git pull

# Update plugins/themes if needed # wp plugin update --all # wp theme update --all

# Clear object cache wp cache flush

# Clear OPCache sudo systemctl reload php8.2-fpm

# Regenerate rewrite rules wp rewrite flush

echo "WordPress deployment complete" EOF

chmod +x wp-deploy.sh ```

Step 5: Fix PHP-FPM Pool Configuration

Configure PHP-FPM to properly manage OPCache.

bash
# Edit PHP-FPM pool configuration:
sudo nano /etc/php/8.2/fpm/pool.d/www.conf

```ini ; Enable OPCache status endpoint php_admin_value[opcache.enable] = 1 php_admin_value[opcache.validate_timestamps] = 1 php_admin_value[opcache.revalidate_freq] = 0 php_admin_value[opcache.memory_consumption] = 256 php_admin_value[opcache.interned_strings_buffer] = 16 php_admin_value[opcache.max_accelerated_files] = 10000

; PHP-FPM settings for OPCache pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 1000

; Clear OPCache on worker restart php_admin_value[opcache.fast_shutdown] = 1

; Status endpoint pm.status_path = /php-fpm-status ```

```bash # Restart PHP-FPM sudo systemctl restart php8.2-fpm

# Check status sudo systemctl status php8.2-fpm

# Test PHP-FPM status endpoint curl http://localhost/php-fpm-status

# Check PHP-FPM processes ps aux | grep php-fpm

# Count workers pgrep php-fpm | wc -l ```

Step 6: Set Up OPCache Monitoring

Create monitoring to detect cache issues.

```bash # Create OPCache monitoring script cat > /usr/local/bin/check-opcache.sh << 'EOF' #!/bin/bash # OPCache Health Check

THRESHOLD_MEMORY=90 THRESHOLD_WASTED=10

STATUS=$(php -r " \$status = opcache_get_status(); if (!\$status) { echo 'DISABLED'; exit(1); }

\$memory_used_percent = (\$status['memory_usage']['used_memory'] / \$status['memory_usage']['used_memory'] + \$status['memory_usage']['free_memory']) * 100; \$wasted_percent = \$status['memory_usage']['current_wasted_percentage']; \$cached_scripts = \$status['opcache_statistics']['num_cached_scripts']; \$hit_rate = \$status['opcache_statistics']['opcache_hit_rate'];

echo json_encode([ 'enabled' => \$status['opcache_enabled'], 'memory_used_percent' => round(\$status['memory_usage']['used_memory'] / (\$status['memory_usage']['used_memory'] + \$status['memory_usage']['free_memory']) * 100, 2), 'wasted_percent' => round(\$status['memory_usage']['current_wasted_percentage'], 2), 'cached_scripts' => \$cached_scripts, 'hit_rate' => round(\$hit_rate, 2) ]); ")

echo "$STATUS" | jq .

# Check thresholds MEMORY_USED=$(echo "$STATUS" | jq -r '.memory_used_percent') WASTED=$(echo "$STATUS" | jq -r '.wasted_percent')

if (( $(echo "$MEMORY_USED > $THRESHOLD_MEMORY" | bc -l) )); then echo "WARNING: Memory usage at ${MEMORY_USED}%" exit 1 fi

if (( $(echo "$WASTED > $THRESHOLD_WASTED" | bc -l) )); then echo "WARNING: Wasted memory at ${WASTED}%" exit 1 fi

echo "OPCache healthy" exit 0 EOF

chmod +x /usr/local/bin/check-opcache.sh

# Run check: /usr/local/bin/check-opcache.sh

# Create web endpoint for monitoring: cat > /var/www/html/opcache-status.php << 'EOF' <?php header('Content-Type: application/json');

$status = opcache_get_status();

if (!$status) { http_response_code(503); echo json_encode(['error' => 'OPCache not enabled']); exit; }

echo json_encode([ 'enabled' => $status['opcache_enabled'], 'memory' => [ 'used' => round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . ' MB', 'free' => round($status['memory_usage']['free_memory'] / 1024 / 1024, 2) . ' MB', 'wasted' => round($status['memory_usage']['current_wasted_percentage'], 2) . '%', ], 'statistics' => [ 'cached_scripts' => $status['opcache_statistics']['num_cached_scripts'], 'hits' => $status['opcache_statistics']['hits'], 'misses' => $status['opcache_statistics']['misses'], 'hit_rate' => round($status['opcache_statistics']['opcache_hit_rate'], 2) . '%', ], 'validate_timestamps' => ini_get('opcache.validate_timestamps'), 'revalidate_freq' => ini_get('opcache.revalidate_freq'), ], JSON_PRETTY_PRINT); EOF

# Test endpoint: curl http://localhost/opcache-status.php | jq . ```

Step 7: Handle Multiple PHP-FPM Workers

Clear cache for all PHP-FPM workers.

```bash # PHP-FPM has multiple workers with separate caches # Simple reload doesn't always clear all

# Force restart to clear all: sudo systemctl restart php8.2-fpm

# Or use process signals: sudo pkill -USR2 php-fpm

# Clear via all workers: # Create a script that hits multiple endpoints:

cat > /usr/local/bin/clear-all-opcache.sh << 'EOF' #!/bin/bash # Clear OPCache for all PHP-FPM workers

# Method 1: HTTP-based clear (hits all workers eventually) for i in {1..20}; do curl -s http://localhost/opcache-clear-all.php > /dev/null & done wait

# Method 2: Force PHP-FPM restart sudo systemctl restart php8.2-fpm

# Wait for restart sleep 2

# Verify php -r " \$status = opcache_get_status(); echo 'Cached scripts: ' . \$status['opcache_statistics']['num_cached_scripts'] . PHP_EOL; "

echo "OPCache cleared for all workers" EOF

chmod +x /usr/local/bin/clear-all-opcache.sh

# Alternative: Use PHP-FPM's reload feature multiple times # This forces workers to restart one by one sudo systemctl reload php8.2-fpm sleep 1 sudo systemctl reload php8.2-fpm sleep 1 sudo systemctl reload php8.2-fpm ```

Step 8: Optimize OPCache Settings

Tune OPCache for production.

bash
# Edit OPCache configuration:
sudo nano /etc/php/8.2/fpm/conf.d/10-opcache.ini

```ini ; Recommended production settings:

; Enable OPCache opcache.enable=1 opcache.enable_cli=0

; Check file timestamps (set to 0 in production for performance) opcache.validate_timestamps=0

; When validate_timestamps=1, check every N seconds ; When validate_timestamps=0, this is ignored opcache.revalidate_freq=60

; Memory allocation (adjust based on app size) opcache.memory_consumption=512

; Interned strings buffer (increase for many strings) opcache.interned_strings_buffer=32

; Max files to cache (count your PHP files) opcache.max_accelerated_files=50000

; Max wasted memory percentage before restart opcache.max_wasted_percentage=5

; Use current working directory for cache keys opcache.use_cwd=1

; Enable file override for better memory usage opcache.override_lru_sort=1

; Save doc comments (required for Doctrine annotations) opcache.save_comments=1

; Load comments only for cached files opcache.load_comments=1

; Fast shutdown (don't free memory on shutdown) opcache.fast_shutdown=1

; Enable CLI for debugging (disable in production) opcache.enable_cli=0

; Validate permissions opcache.validate_permission=0

; Validate root path opcache.validate_root=0

; Protect memory from corruption opcache.protect_memory=1

; File cache for persistence (optional) opcache.file_cache=/var/cache/opcache opcache.file_cache_only=0 opcache.file_cache_consistency_checks=1

; Blacklist files from caching opcache.blacklist_filename=/etc/php/8.2/fpm/opcache-blacklist.txt

; JIT compiler (PHP 8.0+) opcache.jit_buffer_size=100M opcache.jit=1255 ```

```bash # Create cache directory sudo mkdir -p /var/cache/opcache sudo chown www-data:www-data /var/cache/opcache sudo chmod 775 /var/cache/opcache

# Create blacklist file sudo touch /etc/php/8.2/fpm/opcache-blacklist.txt

# Add patterns to blacklist: cat > /etc/php/8.2/fpm/opcache-blacklist.txt << 'EOF' # Blacklist development files /var/www/html/*.test.php /var/www/html/debug.php /var/www/html/vendor/phpunit/* /var/www/html/tests/* EOF

# Restart PHP-FPM sudo systemctl restart php8.2-fpm

# Verify configuration php -i | grep opcache ```

Step 9: Debug Specific Script Issues

Investigate why specific files aren't updating.

```bash # Check if specific file is cached: php -r " \$status = opcache_get_status(); \$file = '/var/www/app/src/MyClass.php'; if (isset(\$status['scripts'][\$file])) { echo \"File is cached: \$file\n\"; print_r(\$status['scripts'][\$file]); } else { echo \"File not in cache: \$file\n\"; } "

# Invalidate specific file: php -r " \$file = '/var/www/app/src/MyClass.php'; if (function_exists('opcache_invalidate')) { \$result = opcache_invalidate(\$file, true); echo 'Invalidated: ' . (\$result ? 'Yes' : 'No') . \"\n\"; } "

# Check if file path matches: ls -la /var/www/app/src/MyClass.php realpath /var/www/app/src/MyClass.php

# Check if symlinks causing issues: readlink -f /var/www/app/src/MyClass.php

# Compare with cached path: php -r " \$status = opcache_get_status(); foreach (\$status['scripts'] as \$path => \$info) { if (strpos(\$path, 'MyClass') !== false) { echo \$path . PHP_EOL; } } "

# Check for path case sensitivity issues: php -r " echo 'Realpath: ' . realpath('/var/www/app/src/myclass.php') . PHP_EOL; echo 'Requested: /var/www/app/src/MyClass.php' . PHP_EOL; "

# Verify file actually changed: md5sum /var/www/app/src/MyClass.php git diff HEAD~1 /var/www/app/src/MyClass.php ```

Step 10: Implement Zero-Downtime Cache Clear

Set up cache clearing that doesn't impact running requests.

```bash # Graceful PHP-FPM reload (waits for running requests) sudo systemctl reload php8.2-fpm

# Create deployment script with graceful cache clear: cat > deploy-with-cache.sh << 'EOF' #!/bin/bash set -e

APP_DIR="/var/www/app" MAINTENANCE_FILE="/var/www/app/.maintenance"

cd $APP_DIR

# Enable maintenance mode touch $MAINTENANCE_FILE

# Wait for running requests to complete (grace period) echo "Waiting for running requests..." sleep 5

# Pull new code git pull origin main

# Install/update dependencies composer install --no-dev --optimize-autoloader

# Run any migrations php bin/console doctrine:migrations:migrate --no-interaction

# Clear application caches php bin/console cache:clear --env=prod

# Warm up cache php bin/console cache:warmup --env=prod

# Clear OPCache gracefully # Method 1: Reload (graceful) sudo systemctl reload php8.2-fpm

# Method 2: If reload doesn't work, use restart # sudo systemctl restart php8.2-fpm

# Wait for PHP-FPM to be ready sleep 2

# Verify application works curl -f http://localhost/health || { echo "Application not healthy, rolling back..." git checkout HEAD~1 sudo systemctl reload php8.2-fpm exit 1 }

# Disable maintenance mode rm -f $MAINTENANCE_FILE

echo "Deployment complete!" EOF

chmod +x deploy-with-cache.sh

# Or use rolling restart for multiple servers: cat > /usr/local/bin/rolling-opcache-clear.sh << 'EOF' #!/bin/bash # Rolling OPCache clear for load-balanced servers

SERVERS=("server1" "server2" "server3")

for server in "${SERVERS[@]}"; do echo "Clearing OPCache on $server..."

# Remove from load balancer # (implementation depends on your LB)

# Clear OPCache ssh $server "sudo systemctl reload php8.2-fpm"

# Wait for clearance sleep 5

# Health check if ssh $server "curl -f http://localhost/health"; then echo "$server ready" else echo "$server failed health check!" exit 1 fi

# Add back to load balancer done

echo "All servers updated" EOF

chmod +x /usr/local/bin/rolling-opcache-clear.sh ```

Checklist for Fixing PHP OPCache Issues

StepActionCommandStatus
1Check OPCache configuration`php -i \grep opcache`
2Enable timestamp validationSet opcache.validate_timestamps=1
3Clear OPCache properlysystemctl reload php8.2-fpm
4Configure deployment cache clearAdd to deploy script
5Fix PHP-FPM pool configurationEdit pool config
6Set up OPCache monitoringCreate monitoring script
7Handle multiple PHP-FPM workersRestart or reload
8Optimize OPCache settingsTune for production
9Debug specific script issuesCheck cached paths
10Implement zero-downtime clearGraceful reload

Verify the Fix

After fixing OPCache issues:

```bash # 1. Code changes reflected immediately # Modify a PHP file, refresh page, see changes

# 2. Timestamps are validated php -i | grep "opcache.validate_timestamps" # Should show: opcache.validate_timestamps => 1 => 1

# 3. OPCache resets successfully php -r "var_dump(opcache_reset());" # Should return: bool(true)

# 4. No stale cached scripts php -r " \$status = opcache_get_status(); echo 'Cached scripts: ' . \$status['opcache_statistics']['num_cached_scripts'] . PHP_EOL; " # Should be reasonable number (not thousands of old files)

# 5. Hit rate is good /usr/local/bin/check-opcache.sh # Should exit with code 0

# 6. Memory not wasted php -r " \$status = opcache_get_status(); echo 'Wasted: ' . \$status['memory_usage']['current_wasted_percentage'] . '%' . PHP_EOL; " # Should be low (< 10%)

# 7. Deployment script works ./deploy-with-cache.sh # Should complete without errors

# 8. Application works after cache clear curl http://localhost/health # Should return 200 OK

# 9. No errors in PHP error log tail /var/log/php8.2-fpm/error.log # Should be clean

# 10. Monitoring shows healthy status curl http://localhost/opcache-status.php | jq . # All values should be healthy ```

  • [Fix PHP Composer Out of Memory](/articles/fix-php-composer-out-of-memory) - Composer memory issues
  • [Fix Symfony Cache Corrupted](/articles/fix-symfony-cache-corrupted) - Symfony cache
  • [Fix Laravel Migration Locked](/articles/fix-laravel-migration-locked) - Laravel database
  • [Fix PHP-FPM Pool Exhausted](/articles/fix-php-fpm-pool-exhausted) - PHP-FPM workers
  • [Fix WordPress Fatal Error](/articles/fix-wordpress-fatal-error-uncaught) - WordPress errors
  • [Fix Magento 2 Indexer Stuck](/articles/fix-magento-2-indexer-stuck) - Magento cache
  • [Fix Nginx 502 Bad Gateway](/articles/fix-nginx-reverse-proxy-502) - Nginx proxy