Debugging WordPress: WP_DEBUG, Logs, and Query Monitor

Arafat Islam Sep 6, 2026 5 min read
Debugging WordPress: WP_DEBUG, Logs, and Query Monitor

A white screen, a plugin that silently fails, a page that's slow for reasons nobody can explain — WordPress debugging usually isn't about clever tricks, it's about turning on the visibility tools that are already built into the platform and reading what they tell you. Here's the practical workflow.

Step One: Turn On WP_DEBUG Properly

wp-config.php controls WordPress's built-in debug behavior. The naive define('WP_DEBUG', true); alone will print errors directly onto the page — fine for a local environment, dangerous on a live site since it can leak file paths and other details to visitors. Use this combination instead:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

This logs every notice, warning, and fatal error to wp-content/debug.log without showing anything to visitors. On a production site, this is the only safe configuration — never set WP_DEBUG_DISPLAY to true where the public can see it.

For more granular control, also enable script debugging to load unminified core JS/CSS when tracking down front-end issues:

define( 'SCRIPT_DEBUG', true );

Reading the Debug Log

wp-content/debug.log grows quickly on an active site, so grep for what you care about rather than scrolling:

tail -f wp-content/debug.log

grep -i "fatal error" wp-content/debug.log

grep -i "deprecated" wp-content/debug.log | sort | uniq -c | sort -rn

A few patterns worth knowing:

  • PHP Fatal error — execution stopped; this is always worth fixing immediately.
  • PHP Deprecated — usually a plugin or theme calling something core will remove in a future version. Not urgent individually, but a large volume from one plugin is a signal it's poorly maintained.
  • PHP Notice: Undefined array key / Undefined variable — often harmless but sometimes indicates broken logic further up the call stack. Worth a quick look, not necessarily an emergency.

Rotate or clear debug.log periodically — it has no built-in size cap and can grow to gigabytes on a busy, error-prone site.

Query Monitor: The Single Most Useful Debugging Plugin

If you install exactly one debugging tool, make it Query Monitor. It adds an admin-bar panel showing, for the current page load:

  • Every database query, with execution time, the calling function, and duplicate-query detection.
  • All hooks fired on the page and what's attached to them.
  • HTTP API requests made during the request (calls to external APIs, webhooks).
  • PHP errors and warnings, attributed to the specific plugin or theme that caused them.
  • Template hierarchy — exactly which template file WordPress chose to render and why.
  • Enqueued scripts and styles, with dependencies.
  • Memory usage and page generation time.

This turns "the site feels slow" into "Plugin X is running 340 duplicate queries on every page load" in about ten seconds. It's safe to leave active on a staging environment, and it respects capability checks so regular visitors on production never see it even if left active (though it's best restricted to admins via its settings).

Isolating a Plugin or Theme Conflict

When something breaks after an update and the error log isn't specific enough:

  1. Switch to a default theme (Twenty Twenty-Five or similar) temporarily. If the issue disappears, it's theme-related.
  2. Deactivate all plugins, then reactivate them one at a time, checking after each. This is tedious but reliably isolates the culprit.
  3. Use the Health Check & Troubleshooting plugin instead of the manual method above — it lets you enable a troubleshooting mode that disables plugins and switches themes only for your own session, leaving the live site untouched for other visitors.

Debugging White Screens of Death

A blank white page with no error message usually means a fatal error occurred but WP_DEBUG_DISPLAY is off (correct for production) and nothing is being logged (a config gap). Fix the visibility first:

  1. Confirm WP_DEBUG_LOG is enabled and check debug.log.
  2. If nothing appears there either, check the web server's own PHP error log (error_log in Apache, or your PHP-FPM pool log) — sometimes the fatal happens before WordPress's own error handling is even loaded.
  3. If you have shell access, increase PHP's memory_limit temporarily and check for "Allowed memory size exhausted" — a common and easy-to-fix cause of blank pages.

Debugging Slow Pages

  • Use Query Monitor's query list to spot N+1 patterns — a loop that fires one query per item instead of one query total is the most common performance bug in custom WordPress code.
  • Check the HTTP API panel for outbound requests blocking page generation — a plugin calling a slow third-party API synchronously on every page load is a frequent, hard-to-spot cause of latency.
  • Compare WP_DEBUG timing output against a caching plugin's cache-hit/miss status — a "slow" page that's actually served from cache points you toward the caching layer, not PHP execution.

Debugging AJAX and REST API Requests

Browser DevTools' Network tab is essential here — inspect the raw response body of failed admin-ajax.php or /wp-json/ requests directly, since WordPress often returns a JSON error object with a specific code and message rather than a generic HTTP status. For REST API issues specifically, appending ?_wpnonce= mismatches or permission callback failures usually show up clearly in that response body once you're actually looking at it instead of just the status code.

Turn It Off When You're Done

WP_DEBUG_LOG writing continuously has a small but real performance cost, and a forgotten WP_DEBUG_DISPLAY left on is a real security and professionalism issue. Treat debug mode as a tool you switch on deliberately for an investigation and switch back off — via a staging environment or a scoped session tool like Health Check — rather than a permanent production setting.