Bali, Indonesia
Insights

Practical Notes on WordPress Performance & Debugging for Everyday Troubleshooting

October 16, 2026
0:00
When a WordPress site begins loading slowly or returns gateway errors during traffic peaks, the instinctive reaction is often to install another caching plugin or raise PHP memory limits. In day-to-day hosting support, I see this create secondary issues far more often than it solves the underlying bottleneck. Page caching only hides performance problems for anonymous traffic, leaving authenticated administrative requests, dynamic carts, and back-end tasks running on the same degraded foundation. Treating performance debugging as a process of elimination rather than a guessing game saves hours of trial and error. The goal is to determine where time is actually spent: inside PHP execution, waiting on the database engine, waiting on external network calls, or stalled in the web server's request queue.
A common misunderstanding among site owners is that a high cache-hit ratio means the site is fundamentally healthy. Full-page caching solutions, whether managed at the web server layer (like LiteSpeed Cache or Nginx FastCGI microcaching) or inside PHP, save generated HTML to disk or memory. When a visitor requests a cached page, PHP and MySQL are completely bypassed. The breakdown happens as soon as an uncached request comes in. Any request that sets a custom session cookie, bypasses cache via dynamic query strings, or hits wp-admin must execute the full WordPress application lifecycle. If the application takes three seconds to assemble a page, every administrative edit, checkout attempt, or background cron worker will take at least that long. When a site owner notices that the frontend seems reasonably responsive while their dashboard is crawling, the issue is almost never the network interface or server memory capacity. We explored this operational split in detail in Why WordPress Admin Is Slow Even When the Frontend Loads Fast. If the uncached execution is slow, the application layer itself needs auditing.
When troubleshooting an unresponsive or slow WordPress instance, the execution flow can be separated into three main buckets:
  1. PHP processing time: Theme templates, custom hooks, and plugin logic doing heavy computational work, parsing large files, or looping through oversized arrays.
  2. Database wait time: Unindexed queries, excessively large single queries, or bloated option tables.
  3. External network blocking: Plugins calling third-party REST APIs, licensing servers, payment gateways, or tracking endpoints synchronously during the page render.
Of these three, external network stalls are frequently overlooked. If a plugin sends an HTTP request using wp_remote_get() during an administrative page load, and the remote endpoint takes five seconds to respond or times out, the PHP worker waits idle for five seconds before rendering the page. To the user, it feels like the local server is completely frozen. To see if PHP is crashing silently or hitting resource exhaustion, inspecting the core debug logs is the first safe step. Rather than displaying errors directly to the browser on a production site, WordPress allows logging them cleanly to a file on disk.
BASH
# Enable debug logging in wp-config.php safely without frontend display
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
@ini_set('display_errors', 0);
Once these constants are placed in wp-config.php, PHP errors, deprecated notices, and fatal exceptions are written to wp-content/debug.log. When reviewing this log, look specifically for Fatal error: Allowed memory size of ... bytes exhausted. When memory exhaustion occurs repeatedly on general pages, it often traces back to bloated configuration records loaded on every request, an issue covered in Auditing Autoloaded Options to Stop Recurring WordPress Out-of-Memory Errors.
Troubleshooting live performance problems directly in the browser can be misleading because browser extensions, local cache, and CDN edge routing alter the perceived latency. Working directly over SSH provides much cleaner diagnostics. WP-CLI provides a direct way to interact with the WordPress core without web server overhead. If you have administrative shell access on a staging server or test VPS, you can measure database query times and verify whether specific plugins are driving up query counts.
BASH
# Inspect active plugins and check database connection response via WP-CLI
wp plugin list --status=active
wp db check
wp eval 'timer_start(); wp(); echo "Page execution time: " . timer_stop() . " seconds
";'
The timer evaluation above runs the core query routing without sending headers or rendering template output, giving you a quick baseline for how long WordPress core and the active plugin stack take just to bootstrap the query. If a clean WordPress installation on the same machine finishes this in 0.05 seconds while the problem site takes 1.8 seconds, you know immediately that active code or database bloat is the problem, not the hosting environment's base I/O or CPU allocation. Another diagnostic practice is temporarily disabling plugins to check for execution drops. Instead of deactivating plugins through the web interface (which might trigger database cleanup hooks or alter user options), you can temporarily rename the active plugin folder on a staging site or use WP-CLI to toggle them systematically while measuring execution times.
Another common misconception involves WordPress transients. Transients are intended to store temporary cached data in the database using the Options API, accompanied by an expiration timestamp. Many plugins use transients to store the results of expensive remote API calls or heavy database queries. However, by default on systems without a persistent memory cache (such as Redis or Memcached), transients are stored directly in the wp_options table. If a plugin writes hundreds of transient entries with differing keys and forgets to clean them up, the options table grows dramatically. Furthermore, if a persistent object cache is not running, expired transients are only cleared when someone attempts to access them or when a scheduled cleanup cron runs. When a site experiences irregular freezes followed by brief periods of normal response times, check the scheduled tasks using WP-CLI via wp cron event list. If the WordPress virtual cron is backed up with dozens of overdue tasks, background processes will piggyback onto normal incoming visitor requests, slowing down random page loads for unsuspecting visitors.
Effective WordPress troubleshooting comes down to isolating the layer that holds the request open. Before adjusting memory limits, moving servers, or layering on additional optimization plugins, check debug.log for fatal errors, check your query counts and database size, and confirm whether external network requests are stalling PHP workers. Treating the symptom with an aggressive cache often masks structural problems that inevitably resurface under load.