WordPress cron job monitoring and debugging process on a server

How to Monitor and Debug Long-Running WordPress Cron Jobs

, , , ,

Series: WordPress Performance on DirectAdmin (Rocky Linux 9)

Phase 4: Cron, Automation & Background Tasks — Part 16 of 30

How to Monitor and Debug Long-Running WordPress Cron Jobs

WordPress relies on cron jobs for scheduled tasks such as publishing posts, running backups, and executing plugin jobs. On DirectAdmin-managed Rocky Linux 9 servers, long-running cron jobs can degrade performance, cause PHP-FPM pool exhaustion, and block essential site operations. This article explains practical methods for monitoring, debugging, and tuning WordPress cron jobs in this environment, with a focus on safe, reproducible steps for sysadmins.

Understanding WordPress Cron on DirectAdmin

By default, WordPress uses a pseudo-cron system, triggered by site traffic. For reliability, most sysadmins disable this and set up a real cron job via DirectAdmin or system cron. On DirectAdmin with Rocky Linux 9, sites usually run under PHP-FPM pools with either Apache or NGINX as the web server.

  • Default WordPress cron path: /home/USERNAME/domains/DOMAIN/public_html/wp-cron.php
  • PHP-FPM pool location: /usr/local/directadmin/data/users/USERNAME/php-fpmXX.conf (XX = PHP version)

Key Risks with Long-Running Cron Jobs

  • PHP-FPM pool exhaustion, leading to 502/504 errors for site visitors.
  • Overlapping jobs causing database contention or deadlocks.
  • Incomplete or duplicate task execution due to timeouts.

Checklist: Monitoring WordPress Cron Health

  1. Disable WP’s built-in pseudo-cron by adding to wp-config.php:
    define('DISABLE_WP_CRON', true);
  2. Ensure a real cron is configured via DirectAdmin or crontab -e:
    */5 * * * * cd /home/USERNAME/domains/DOMAIN/public_html && /usr/local/bin/php74 -q wp-cron.php >/dev/null 2>&1

    Adjust php74 to your PHP version/binary as needed.

  3. List scheduled events and next run times via WP-CLI:
    sudo -u USERNAME -i -- wp cron event list --path=/home/USERNAME/domains/DOMAIN/public_html --fields=hook,next_run,status
  4. Monitor PHP-FPM pool status (per domain):
    • Find pool name in php-fpmXX.conf (usually USERNAME or DOMAIN.TLD).
    • Query PHP-FPM status (if enabled):
    • curl http://127.0.0.1:YOUR_STATUS_PORT/status?json
    • If status not enabled, enable pm.status_path in PHP-FPM pool config, restart PHP-FPM:
    • sudo systemctl restart php-fpm74
  5. Inspect recent cron executions in logs:
    • Apache: /var/log/httpd/domains/DOMAIN.TLD.log
    • NGINX: /var/log/nginx/domains/DOMAIN.TLD.log
    • PHP-FPM: /var/log/php-fpm/DOMAIN.TLD.log or pool-specific logs
  6. Monitor system load and PHP processes:
  7. sudo top -u USERNAME
  8. ps -ef | grep php-fpm

Debugging Long-Running or Stuck Cron Jobs

Step 1: Identify Long-Running Hooks

  • Use WP-CLI to get current cron events and status:
    sudo -u USERNAME -i -- wp cron event list --path=/home/USERNAME/domains/DOMAIN/public_html
  • Check for jobs with ‘now’ or overdue times, or ‘processing’ status (some plugins use custom statuses).

Step 2: Manually Trigger and Time Jobs

  • Trigger all due events and time execution:
    time sudo -u USERNAME -i -- wp cron event run --due-now --path=/home/USERNAME/domains/DOMAIN/public_html
  • If this takes >60s, review which hooks are slow. For more granularity, run specific hooks:
  • sudo -u USERNAME -i -- wp cron event run HOOK_NAME --path=/home/USERNAME/domains/DOMAIN/public_html

Step 3: Increase Logging for Troubleshooting

  1. Enable WP_DEBUG in wp-config.php:
    define('WP_DEBUG', true);
    define('WP_DEBUG_LOG', true);
    define('WP_DEBUG_DISPLAY', false);

    Log output will go to wp-content/debug.log. Remember to disable after debugging to avoid performance issues.

  2. For PHP errors, check /var/log/php-fpm/DOMAIN.TLD.log or global /var/log/php-fpm/error.log.

Step 4: Analyze PHP-FPM Pool Resource Usage

  • Edit the pool config (/usr/local/directadmin/data/users/USERNAME/php-fpmXX.conf) to log slow requests:
  • request_slowlog_timeout = 10s
    slowlog = /var/log/php-fpm/DOMAIN.TLD-slow.log
  • Reload PHP-FPM:
  • sudo systemctl reload php-fpm74
  • Check slowlog for evidence of stuck or expensive jobs:
  • tail -n 50 /var/log/php-fpm/DOMAIN.TLD-slow.log

Tuning for Long-Running Cron Jobs

PHP-FPM Pool Tuning

  • For sites with heavy cron, increase pm.max_children and pm.max_requests in pool config. Good starting values for medium sites:
    pm = ondemand
    pm.max_children = 10
    pm.max_requests = 500
  • After editing, restart PHP-FPM:
  • sudo systemctl restart php-fpm74
  • Warning: Setting max_children too high may exhaust server RAM. Monitor htop or free -m after changes.

Timeouts and Overlap Protection

  • Set a sensible timeout in your cron command. Example using timeout (EL9 default):
    */5 * * * * timeout 180 /usr/local/bin/php74 -q /home/USERNAME/domains/DOMAIN/public_html/wp-cron.php >/dev/null 2>&1

    This kills jobs longer than 3 minutes. Tune as needed.

  • Some plugins (e.g., WP All Import, backup plugins) need higher timeouts; check their docs.
  • Consider using a lockfile to avoid overlapping runs:
    */5 * * * * flock -n /tmp/wp-cron-USERNAME.lock /usr/local/bin/php74 -q /home/USERNAME/domains/DOMAIN/public_html/wp-cron.php >/dev/null 2>&1

Simulating and Testing Cron Performance

Simulate Traffic and Cron Load

  • Trigger cron via HTTP to simulate real-world access:
    curl -I https://DOMAIN.TLD/wp-cron.php?doing_wp_cron
  • Benchmark with wrk or k6 (install with sudo dnf install wrk):
    wrk -t4 -c10 -d30s https://DOMAIN.TLD/wp-cron.php?doing_wp_cron
  • Monitor logs for errors or slow responses during load tests.

Live Monitoring Checklist

  • tail -f /var/log/php-fpm/DOMAIN.TLD-slow.log
  • tail -f /home/USERNAME/domains/DOMAIN/public_html/wp-content/debug.log
  • sudo journalctl -u php-fpm74 -f
  • sudo top -u USERNAME

Common Issues and Troubleshooting Steps

  • 502/504 errors: Check PHP-FPM pool exhaustion, increase pm.max_children, and inspect slowlog.
  • Missed events: Ensure system cron is running (sudo systemctl status crond), and that DISABLE_WP_CRON is set in wp-config.php.
  • Stuck jobs: Check for plugin bugs, database locks, or memory exhaustion. Review debug.log and plugin docs.
  • Excessive resource use: Profile with WP-CLI, enable slowlog, and limit concurrent jobs with flock.

Summary: Practical Workflow

  1. Disable pseudo-cron and use real cron for reliability.
  2. Monitor scheduled events and event status with WP-CLI.
  3. Enable and watch slowlogs and debug logs for job profiling.
  4. Test cron performance with manual runs and load tools.
  5. Tune PHP-FPM pools for capacity, monitor after changes, and use lockfiles or timeouts to prevent overload.
  6. Document any changes to DirectAdmin custom templates for pool configs to ensure future updates don’t overwrite your tuning. (See earlier series articles on safe template overrides.)

Note: This article offers general technical guidance. Validate all configurations in a safe environment before applying them to production.

Further Reading

Previous: Scheduled Posts Not Publishing? WP-Cron Timing Explained

Next: Apache Performance Tuning for WordPress on DirectAdmin

Smart reads for curious minds

We don’t spam! Read more in our privacy policy