WordPress Performance Optimization

Complete NGINX Configuration Guide for High-Performance WordPress Sites

WordPress Cron Optimization

What is WordPress Cron?

The WordPress cron system is used to schedule tasks to run at intervals on your WordPress site. Some examples include scheduling when you want a post to be published, checking for updates, or running a backup plugin at a specific time.

Why Optimize WP Cron?

Unfortunately, as your site traffic increases, so does the resource demands that WordPress cron makes on your server. Eventually, it will start to slow down your server. Running a cron from the server side is much more efficient when compared to a WordPress cron, as the server doesn't need to involve PHP and will execute the cron with minimal resource demands.

WordPress Cron vs Server Cron

WordPress Cron (Default)

❌ Runs on every page load

❌ High PHP resource usage

❌ Unreliable timing

❌ Slows down site

Server Cron (Optimized)

✅ Runs independently

✅ Minimal resource usage

✅ Precise timing

✅ Better performance

Implementation Steps

Step 1: Disable WordPress Cron

First, we need to open the wp-config.php file and disable the built-in WordPress cron:

Navigate to site directory
cd /var/www/example.com/
Edit wp-config.php
sudo nano public_html/wp-config.php

Add the following line to wp-config.php:

define('DISABLE_WP_CRON', true);
Restart PHP-FPM
sudo systemctl restart php8.3-fpm

Step 2: Create Server-Side Cron Job

Now we'll create a server-side cron job that will run as your non-root user:

Open crontab editor
crontab -e

Select nano as your editor (usually option 1: /bin/nano)

Add cron job (runs every 15 minutes)
*/15 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Important: Replace example.com with your actual domain name.

Cron Schedule Explanation

Position Field Value Description
1 Minutes */15 Every 15 minutes
2 Hours * Every hour
3 Day of Month * Every day
4 Month * Every month
5 Day of Week * Every day of week

Step 3: Verify Cron Job

List current cron jobs
crontab -l

Recommended Frequency: Every 15 minutes is a good starting point for most sites. You can reduce this to as low as every minute if your site requires more frequent cron execution, depending on your specific requirements.

WordPress Post Revisions Management

WordPress automatically saves revisions of your posts and pages. While this feature can be helpful for recovering old content, it can also bloat your database over time. Disabling post revisions can help keep your database lean and improve performance.

Disable Post Revisions

Navigate to site directory
cd /var/www/example.com/
Edit wp-config.php
sudo nano public_html/wp-config.php

Add the following line to wp-config.php:

define('WP_POST_REVISIONS', false);
Restart PHP-FPM
sudo systemctl restart php8.3-fpm

Note: You can also limit the number of revisions by setting a numeric value instead of false. For example: define('WP_POST_REVISIONS', 3); will keep only the last 3 revisions.

PHP Memory Limit Configuration

Increasing the PHP memory limit allows WordPress to handle more complex operations and larger plugins without running into memory exhaustion errors.

Configure PHP Pool Memory Limit

Navigate to PHP-FPM pool directory
cd /etc/php/8.3/fpm/pool.d/
Edit site-specific pool configuration
sudo nano example.com.conf

Add or modify the following line:

php_admin_value[memory_limit] = 256M

Comment out any lower memory limits:

;php_admin_value[memory_limit] = 32M

Configure WordPress Memory Limit

Edit wp-config.php
sudo nano /var/www/example.com/public_html/wp-config.php

Add the following line to wp-config.php:

define('WP_MEMORY_LIMIT', '256M');

Memory Limit Hierarchy

PHP ini settings
(Lowest priority)
PHP-FPM Pool Configuration
(php_admin_value overrides PHP ini)
WordPress wp-config.php
(WP_MEMORY_LIMIT sets WordPress limit)

OPCache Configuration

OPCache is a PHP opcode cache that stores precompiled script bytecode in shared memory, eliminating the need for PHP to load and parse scripts on each request. This dramatically improves PHP performance.

Configuration Steps

Navigate to PHP-FPM pool directory
cd /etc/php/8.3/fpm/pool.d/
List pool configurations
ls
Edit site pool configuration
sudo nano example.com.conf

Development Server Configuration

Add these directives for development environments:

; OPCACHE CONFIGURATION - DEVELOPMENT SERVER - Jul 2025
; Directive php_admin_flag[opcache.enabled] leave commented - enabled by default
; php_admin_flag[opcache.enabled] = 1
php_admin_value[opcache.memory_consumption] = 256
php_admin_value[opcache.interned_strings_buffer] = 32
php_admin_value[opcache.max_accelerated_files] = 20000
php_admin_flag[opcache.validate_timestamps] = 1
php_admin_value[opcache.revalidate_freq] = 2
php_admin_flag[opcache.validate_permission] = 1

Production Server Configuration

For production environments (better performance):

; OPCACHE CONFIGURATION - PRODUCTION SERVER - Jul 2025
; Directive php_admin_flag[opcache.enabled] leave commented - enabled by default
;php_admin_flag[opcache.enabled] = 1
;php_admin_value[opcache.memory_consumption] = 256
;php_admin_value[opcache.interned_strings_buffer] = 32
;php_admin_value[opcache.max_accelerated_files] = 20000
;php_admin_value[opcache.validate_timestamps] = 0
;php_admin_flag[opcache.validate_permission] = 1
Directive Description Recommended Value
memory_consumption Amount of memory for OPCache 256 MB
interned_strings_buffer Memory for interned strings 32 MB
max_accelerated_files Maximum cached files 20000
validate_timestamps Check file changes (1=dev, 0=prod) 1 (dev) / 0 (prod)
revalidate_freq Check frequency in seconds (dev only) 2 seconds

Calculate Maximum Accelerated Files

Count PHP files in your site
cd /var/www/
sudo find . -type f -print | grep php | wc -l

Set max_accelerated_files to a value higher than the number of PHP files. The value must be a power of 2 (e.g., 2000, 4000, 8000, 16000, 20000).

Reference: PHP OPCache Documentation

Reload PHP-FPM
sudo systemctl reload php8.3-fpm

NGINX FastCGI Cache

FastCGI caching is a powerful NGINX feature that stores the output of PHP scripts, allowing NGINX to serve cached content without executing PHP, resulting in dramatic performance improvements.

Important Note: Cloudflare has deprecated auto-minification features. Reference: Cloudflare Auto-Minify Deprecation

Configuration Overview

FastCGI Cache Flow

1. Request arrives at NGINX
2. Check cache exclusions
(Skip cache if excluded)
3. Check if cached version exists
4a. Serve from cache
(Fast response)
OR
4b. Execute PHP & cache result
(First request or cache miss)

Step 1: Configure HTTP Context

Edit NGINX main configuration
cd /etc/nginx
sudo nano nginx.conf

Add before "# Virtual Host Configs" section:

### FASTCGI CACHING
# fastcgi_cache_path directive - PATH & NAME must be unique for each site
# Add a new fastcgi_cache_path for each site and give a new keys_zone name
fastcgi_cache_path /var/run/SITE levels=1:2 keys_zone=NAME:100m inactive=60m;
# applied to all sites
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

Important: Replace SITE with your cache directory name and NAME with a unique cache zone name for each site.

Step 2: Create Cache Exclusions File

Create includes directory file
cd /etc/nginx/includes/
sudo nano fastcgi_cache_excludes.conf

Add the following exclusion rules:

# NGINX SKIP CACHE INCLUDE FILE
set $skip_cache 0;
# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
    set $skip_cache 1;
}
if ($query_string != "") {
    set $skip_cache 1;
}
# Don't cache uris containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
    set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;
}

Step 3: Configure Server Block

Edit site configuration
cd /etc/nginx/sites-available
sudo nano example.com.conf

Add these directives to your server block:

include /etc/nginx/includes/fastcgi_cache_excludes.conf;
add_header X-FastCGI-Cache $upstream_cache_status;

In the PHP location block, add:

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache NAME;
fastcgi_cache_valid 60m;

Step 4: Add Cache Purge Location (Optional)

Add cache purge functionality:

location ~ /purge(/.*) {
    fastcgi_cache_purge NAME "$scheme$request_method$host$1";
}

You can use any name instead of /purge/

Step 5: Test and Reload

Test NGINX configuration
sudo nginx -t
Reload NGINX
sudo systemctl reload nginx
Restart PHP-FPM
sudo systemctl restart php8.3-fpm

Verify Cache Status

Check cache headers
curl -I https://example.com
curl -I https://www.example.com

Cache Status Headers:

  • HIT - Content served from cache
  • MISS - Cache miss, content generated by PHP
  • BYPASS - Cache bypassed due to exclusion rules
  • EXPIRED - Cached content expired, regenerating

Removing FastCGI Cache

Edit site configuration
cd /etc/nginx/sites-available
sudo nano example.com.conf

To remove FastCGI caching:

  1. Remove: include /etc/nginx/includes/fastcgi_cache_excludes.conf;
  2. Comment out: fastcgi_cache_bypass $skip_cache;
  3. Comment out: fastcgi_no_cache $skip_cache;
  4. Comment out: fastcgi_cache NAME;
  5. Comment out: fastcgi_cache_valid 60m;
  6. Comment out: add_header X-FastCGI-Cache $upstream_cache_status;
  7. Remove the purge location block
Test and reload
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart php8.3-fpm

WP Super Cache with NGINX

WP Super Cache is a popular WordPress caching plugin that generates static HTML files from your dynamic WordPress site. When configured properly with NGINX, it can serve cached content directly without loading PHP or querying the database.

Step 1: Create Cache Exclusions File

Create WP Super Cache exclusions
cd /etc/nginx/includes/
sudo nano wp_super_cache_excludes.conf

Add the following configuration:

# WP Super Cache NGINX Cache Exclusions Rules.
set $cache_uri $request_uri;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
    set $cache_uri 'null cache';
}

if ($query_string != "") {
    set $cache_uri 'null cache';
}

# Don't cache uris containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
    set $cache_uri 'null cache';
}

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
    set $cache_uri 'null cache';
}

# Use cached or actual file if they exists, otherwise pass request to WordPress
location / {
    try_files /wp-content/cache/supercache/$http_host/$cache_uri/index-https.html $uri $uri/ /index.php?$args ;
}

Step 2: Configure Server Block

Edit site configuration
cd /etc/nginx/sites-available/
sudo nano example.com.conf

Add the include directive:

include /etc/nginx/includes/wp_super_cache_exclusions.conf;
Test and reload NGINX
sudo nginx -t
sudo systemctl reload nginx

Uninstalling WP Super Cache

Edit site configuration
cd /etc/nginx/sites-available/
sudo nano example.com.conf

Remove the include directive:

include /etc/nginx/includes/wp_super_cache_exclusions.conf;

Uncomment the standard location block:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}
Test and reload services
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl reload php8.3-fpm

W3 Total Cache with NGINX

W3 Total Cache is a comprehensive caching plugin that improves WordPress performance through page caching, browser caching, object caching, and CDN integration.

Step 1: Prepare NGINX Configuration File

Create nginx.conf in site root
cd /var/www/example.com/public_html/
sudo touch nginx.conf
sudo chown username:username nginx.conf
sudo chmod 660 nginx.conf
sudo ls -l

Security Note: Replace username:username with your actual user and group.

Step 2: Secure NGINX Configuration Access

Add security directive
cd /etc/nginx/includes/
sudo nano nginx_security_directives.conf

Add this directive:

location = /nginx.conf { deny all; }

Step 3: Create W3TC Cache Exclusions

Create exclusions file
cd /etc/nginx/includes/
sudo nano w3tc_cache_excludes.conf

Add the following configuration:

# ---------------------
# W3 TOTAL CACHE EXCLUDES FILE
# ---------------------
set $cache_uri $request_uri;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
    set $cache_uri 'null cache';
}
if ($query_string != "") {
    set $cache_uri 'null cache';
}
# Don't cache uris containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
    set $cache_uri 'null cache';
}
# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
    set $cache_uri 'null cache';
}
# Use cached or actual file if file exists, otherwise pass request to WordPress
location / {
    try_files /wp-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args;
}

Step 4: Configure Server Block

Edit site configuration
cd /etc/nginx/sites-available/
sudo nano example.com.conf

Comment out the standard location block:

#location / {
#    try_files $uri $uri/ /index.php$is_args$args;
#}

Add these include directives:

include /etc/nginx/includes/w3tc_cache_excludes.conf;
include /var/www/example.com/public_html/nginx.conf;
Test and reload NGINX
sudo nginx -t
sudo systemctl reload nginx

Step 5: Install PHP Tidy Extension

Install php-tidy (required for W3TC)
sudo apt update
sudo apt install php8.3-tidy
Reload services
sudo systemctl reload nginx
sudo systemctl reload php8.3-fpm

Uninstalling W3 Total Cache

Edit site configuration
cd /etc/nginx/sites-available/
sudo nano example.com.conf

Uncomment the standard location block:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}

Remove these include directives:

include /etc/nginx/includes/w3tc_cache_excludes.conf;
include /var/www/example.com/public_html/nginx.conf;
Remove W3TC cache directories
cd /var/www/example.com/public_html/wp-content/
sudo rm -rf cache/ w3tc-config/
Remove nginx.conf file
cd /var/www/example.com/public_html/
sudo rm nginx.conf
Reload services
sudo systemctl reload php8.3-fpm
sudo systemctl reload nginx

Redis Object Cache

Redis is an in-memory data structure store that can be used as a database, cache, and message broker. For WordPress, Redis object caching can dramatically improve performance by storing database query results in memory.

Installation and Configuration

Install Redis and PHP extension
sudo apt update
sudo apt install redis-server php8.3-redis

Verify Redis Status

Check Redis service status
sudo systemctl status redis-server
Check Redis logs
sudo cat /var/log/redis/redis-server.log

Fix Overcommit Memory Warning

If you see this warning in logs:

WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.

Create sysctl configuration
cd /etc/sysctl.d/
sudo nano 11-redis.conf

Add this line:

vm.overcommit_memory = 1
Reboot system
sudo reboot
Verify after reboot
sudo systemctl status redis-server
sudo cat /var/log/redis/redis-server.log

Configure Redis Memory

Edit Redis configuration
cd /etc/
sudo ls redis/
sudo nano redis/redis.conf

Add or modify these directives:

maxmemory 256mb
maxmemory-policy allkeys-lru
Policy Description
allkeys-lru Evict least recently used keys when memory limit is reached
allkeys-lfu Evict least frequently used keys
volatile-lru Evict least recently used keys with expire set
noeviction Return errors when memory limit is reached
Restart Redis and reboot
sudo systemctl restart redis-server
sudo reboot

Configure WordPress for Redis

Edit wp-config.php
cd /var/www/example.com/public_html/
sudo nano wp-config.php

Add this directive:

define( 'WP_CACHE_KEY_SALT', 'example.com' );

Replace example.com with your actual domain name

WooCommerce Redis Configuration

Important for WooCommerce sites: WooCommerce session data should not be cached by Redis as it can cause cart and checkout issues.

Reference: WooCommerce Caching Configuration

Add this to wp-config.php to prevent caching WooCommerce session data:

/** PREVENT REDIS CACHING WOO SESSION DATA */
define('WP_REDIS_IGNORED_GROUPS', 'wc_session');

WooCommerce Pages and Cookies to Exclude from Caching:

Type Item
Pages /cart/
/my-account/
/checkout/
Cookies woocommerce_cart_hash
woocommerce_items_in_cart
wp_woocommerce_session_
woocommerce_recently_viewed
store_notice[notice id]
_wc_session_

PHP-FPM Process Manager Optimization

PHP-FPM (FastCGI Process Manager) is responsible for managing PHP processes. Proper configuration ensures optimal resource usage and prevents memory exhaustion.

Calculate Optimal Settings

Step 1: Display Pool Usernames

List all pool usernames
grep -E '^\s*user\s*=' /etc/php/8.3/fpm/pool.d/*.conf | awk -F= '{print $2}' | xargs | tr ' ' '\n' | sort -u

Step 2: Calculate Average Memory per Process

Calculate average memory (replace POOL_USER with actual username)
ps -C php-fpm --user POOL_USER -o rss= | awk '{ sum += $1; count++ } END { if (count > 0) printf ("%d%s\n", sum/NR/1024,"M") }'

Example calculation:

If average process memory = 40M and available RAM = 2GB (2048MB):

max_children = 2048MB / 40M = 51 processes

Leave some memory for other services, so use about 80% = 40 processes

Configure OnDemand Process Manager

Edit pool configuration
cd /etc/php/8.3/fpm/pool.d/
ls
sudo nano example.com.conf

Add or modify these directives:

pm = ondemand
pm.max_children = 40
pm.process_idle_timeout = 10s
pm.max_requests = 500
Directive Description Recommended
pm Process manager type ondemand (creates processes as needed)
pm.max_children Maximum number of processes Calculated based on available memory
pm.process_idle_timeout Time before idle process is killed 10 seconds
pm.max_requests Requests before process restart 500
Reload PHP-FPM
sudo systemctl reload php8.3-fpm

Monitor for max_children Issues

Check PHP-FPM logs
ls /var/log/
sudo grep max_children /var/log/php8.3-fpm.log

If you see this warning:

WARNING: [pool www] server reached max_children setting (25), consider raising it

Increase the pm.max_children value in your pool configuration.

PHP-FPM Process Manager Types

Dynamic

✓ Maintains minimum processes

✓ Spawns more as needed

✓ Good for consistent traffic

Static

✓ Fixed number of processes

✓ Predictable memory usage

✓ Best for high traffic

OnDemand (Recommended)

✓ Starts with no processes

✓ Creates as needed

✓ Kills idle processes

✓ Most resource efficient

✓ Best for low-moderate traffic

Cloudflare Integration

When using Cloudflare as a reverse proxy, NGINX needs to be configured to trust Cloudflare's IP addresses and properly log the real visitor IP addresses.

Why Configure Cloudflare IPs?

Without proper configuration, your server logs will show Cloudflare's IP addresses instead of your actual visitors' IPs. This affects:

  • Access logs and analytics
  • Security rules and IP blocking
  • Rate limiting
  • Geolocation features

Get Current Cloudflare IP Ranges

Official Cloudflare IP Lists:

Configuration Steps

Create Cloudflare IP list file
cd /etc/nginx/includes
sudo nano cloudflare_ip_list.conf

Add the following IP ranges (updated October 2022):

# Last updated OCT 2022
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;

Important: Make sure to update these IP ranges periodically as Cloudflare may add new IP addresses. Check the official Cloudflare IP lists regularly.

Apply to Server Block

Edit site configuration
cd /etc/nginx/sites-available/
sudo nano example.com.conf

Add this include directive to your server block:

include /etc/nginx/includes/cloudflare_ip_list.conf;
Test and reload NGINX
sudo nginx -t
sudo systemctl reload nginx

Understanding the Configuration

Directive Purpose
set_real_ip_from Defines trusted proxy IP addresses (Cloudflare's IPs)
real_ip_header Specifies which header contains the real client IP
CF-Connecting-IP Cloudflare's header containing the original visitor IP

Request Flow with Cloudflare

Visitor
IP: 123.45.67.89
Cloudflare Network
Adds CF-Connecting-IP: 123.45.67.89
Your NGINX Server
Reads CF-Connecting-IP header
Logs real IP: 123.45.67.89

Verification: After configuration, check your access logs to ensure they show real visitor IP addresses instead of Cloudflare IPs (which typically start with 104.x, 172.x, or 162.x).

Best Practices and Recommendations

General Guidelines

✅ Do's

  • Always test NGINX configuration before reloading: sudo nginx -t
  • Keep backups of configuration files before making changes
  • Monitor server resources regularly
  • Update Cloudflare IP ranges periodically
  • Test caching behavior after configuration
  • Use descriptive comments in configuration files
  • Document your specific customizations

❌ Don'ts

  • Don't reload NGINX without testing first
  • Don't use the same cache zone name for multiple sites
  • Don't cache logged-in user content
  • Don't cache WooCommerce cart/checkout pages
  • Don't set memory limits too low
  • Don't ignore error logs
  • Don't use production settings in development

Performance Optimization Checklist

Component Optimization Impact
WP Cron Server-side cron 🔥🔥🔥 High
OPCache Enable and configure 🔥🔥🔥 High
FastCGI/Page Cache Enable caching plugin 🔥🔥🔥 High
Redis Object caching 🔥🔥 Medium-High
PHP-FPM OnDemand mode 🔥🔥 Medium
Post Revisions Limit or disable 🔥 Low-Medium
Memory Limit Appropriate sizing 🔥 Medium

Monitoring Commands

Check NGINX status
sudo systemctl status nginx
Check PHP-FPM status
sudo systemctl status php8.3-fpm
Check Redis status
sudo systemctl status redis-server
View NGINX error logs
sudo tail -f /var/log/nginx/error.log
View PHP-FPM error logs
sudo tail -f /var/log/php8.3-fpm.log
Monitor server resources
htop

Troubleshooting Common Issues

Issue: Site returns 502 Bad Gateway

Possible causes:

  • PHP-FPM not running
  • PHP-FPM socket permission issues
  • PHP-FPM process limit reached

Solution: Check PHP-FPM status and logs, verify socket permissions, increase max_children if needed

Issue: Cache not working

Possible causes:

  • Exclusion rules too broad
  • Always receiving logged-in cookies
  • Cache directory permissions

Solution: Check cache headers with curl -I, verify exclusion rules, check directory permissions

Issue: High memory usage

Possible causes:

  • Too many PHP-FPM processes
  • Memory leaks in plugins
  • Insufficient OPCache memory

Solution: Reduce max_children, disable problematic plugins, increase OPCache memory or change settings to production mode

Quick Reference

Essential Commands

NGINX

sudo nginx -t

Test configuration

sudo systemctl reload nginx

Reload configuration

sudo systemctl restart nginx

Restart service

PHP-FPM

sudo systemctl reload php8.3-fpm

Reload configuration

sudo systemctl restart php8.3-fpm

Restart service (clears OPCache)

sudo systemctl status php8.3-fpm

Check status

Important File Locations

Component Location
NGINX main config /etc/nginx/nginx.conf
NGINX site configs /etc/nginx/sites-available/
NGINX includes /etc/nginx/includes/
PHP-FPM pools /etc/php/8.3/fpm/pool.d/
WordPress config /var/www/example.com/public_html/wp-config.php
Redis config /etc/redis/redis.conf
Crontab crontab -e (user-specific)

Log File Locations

Service Log Location
NGINX Access /var/log/nginx/access.log
NGINX Error /var/log/nginx/error.log
PHP-FPM /var/log/php8.3-fpm.log
Redis /var/log/redis/redis-server.log