• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 9+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Step-by-Step: Diagnosing cascading database downtime during admin-ajax.php request spikes on Linode Servers

Step-by-Step: Diagnosing cascading database downtime during admin-ajax.php request spikes on Linode Servers

Identifying the `admin-ajax.php` Bottleneck

Cascading database downtime, particularly when triggered by spikes in admin-ajax.php requests on Linode servers hosting WordPress, often points to a resource exhaustion problem. The admin-ajax.php endpoint is a common culprit because it’s used by numerous plugins and themes for background operations, AJAX requests, and even some security checks. When these requests become excessive, they can overwhelm the database, leading to slow queries, connection timeouts, and ultimately, a complete service outage.

The first step in diagnosis is to confirm that admin-ajax.php is indeed the trigger. This involves correlating traffic spikes with database load. We’ll use server-level tools to monitor request volume and database performance metrics.

Monitoring Request Volume and Source

We need to understand the volume of requests hitting admin-ajax.php and, if possible, their origin. For a Linode server running a typical LEMP or LAMP stack, we can leverage Nginx/Apache access logs and tools like grep and awk.

Analyzing Nginx/Apache Access Logs

Assuming Nginx is used as the web server, access logs are typically found at /var/log/nginx/access.log. For Apache, it’s usually /var/log/apache2/access.log or similar. We’ll filter for admin-ajax.php requests and count them over specific time intervals.

To get a real-time count of admin-ajax.php requests per minute:

tail -f /var/log/nginx/access.log | awk '/\/wp-admin\/admin-ajax.php/ { print strftime("%Y-%m-%d %H:%M"), $7 }' | sort | uniq -c | sort -nr

This command tails the log, filters for the target URL, extracts the timestamp and requested URL (assuming a common log format), and then counts unique occurrences per minute. The output will show the most frequent requests. If you see a massive number of admin-ajax.php requests during downtime, this confirms our hypothesis.

To identify the IP addresses generating the most traffic, modify the awk command:

tail -f /var/log/nginx/access.log | awk '/\/wp-admin\/admin-ajax.php/ { print $1 }' | sort | uniq -c | sort -nr | head -n 20

This will list the top 20 IP addresses making admin-ajax.php requests. If a single IP or a small range dominates, it might indicate a bot, a misbehaving plugin on a specific user’s browser, or a compromised site.

Monitoring Database Performance

While monitoring web traffic, we must simultaneously monitor the database. MySQL/MariaDB is the typical backend for WordPress. We’ll look for high connection counts, slow queries, and CPU/IO utilization on the database server.

Checking MySQL/MariaDB Connections

A common symptom of overload is exceeding the maximum allowed database connections. We can check the current number of connections and the maximum configured limit.

SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';

If Threads_connected is consistently close to or at max_connections during spikes, this is a strong indicator of connection exhaustion. This often leads to new connection attempts failing, which can cascade into application errors.

Identifying Slow Queries

Slow queries are a direct cause of database load. We need to enable and analyze the slow query log.

First, ensure the slow query log is enabled in your MySQL/MariaDB configuration (e.g., my.cnf or my.ini). Add or modify these lines in the [mysqld] section:

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2  # Log queries taking longer than 2 seconds
log_queries_not_using_indexes = 1

Restart the MySQL/MariaDB service after making these changes. Then, use mysqldumpslow to analyze the log file:

mysqldumpslow /var/log/mysql/mysql-slow.log

This command aggregates similar slow queries. Look for queries related to WordPress tables (wp_posts, wp_options, wp_users, etc.) that appear frequently or have a high total execution time. Often, poorly optimized plugin queries or excessive meta lookups will surface here.

Correlating Web Server and Database Metrics

The key to diagnosing cascading downtime is correlating the events. Use tools like htop, iotop, and netstat on the Linode server to observe resource utilization during a suspected spike.

Real-time Resource Monitoring

While the admin-ajax.php spike is occurring:

  • CPU Usage: Run htop. Observe if the mysqld process or the web server processes (nginx, php-fpm) are consuming 100% of CPU.
  • Memory Usage: In htop, check overall memory usage. High swap usage is a critical indicator of memory pressure.
  • Disk I/O: Use iotop (requires root privileges). Look for high read/write activity on the disk where the database files reside. This can indicate the database is struggling to keep up with read/write operations.
  • Network Connections: Use netstat -anp | grep ESTABLISHED | wc -l to see the total number of established connections. Correlate this with the Threads_connected count from MySQL.

If you see high CPU on mysqld, high disk I/O, and a high number of database connections coinciding with admin-ajax.php request spikes, the diagnosis is clear: the excessive AJAX requests are overwhelming the database.

Investigating Plugin and Theme Behavior

Once the bottleneck is identified as the database being overloaded by admin-ajax.php, the next step is to pinpoint *which* plugin or theme is causing this behavior. This often requires a systematic deactivation process.

Disabling Plugins Systematically

The most reliable method is to disable all plugins and then re-enable them one by one, monitoring traffic and database load after each activation. If you can access the WordPress admin area:

  • Go to Plugins > Installed Plugins.
  • Select all plugins.
  • From the Bulk Actions dropdown, choose Deactivate and click Apply.
  • Monitor server load. If it normalizes, the issue was indeed plugin-related.
  • Re-activate plugins one by one, checking server load and admin-ajax.php traffic after each activation. When the load spikes again, the last activated plugin is the likely culprit.

If you cannot access the admin area, you can achieve the same by renaming the wp-content/plugins directory via SSH (e.g., to plugins_old). This deactivates all plugins. Then, rename it back and systematically rename individual plugin directories within wp-content/plugins (e.g., plugin-name to plugin-name_disabled) until the issue is isolated.

Theme-Related AJAX Calls

While less common than plugin issues, themes can also enqueue scripts that make admin-ajax.php calls. If disabling all plugins doesn’t resolve the issue, consider switching to a default WordPress theme (like Twenty Twenty-Two) to rule out theme-specific AJAX activity.

Implementing Solutions and Preventative Measures

Once the problematic plugin or theme is identified, several strategies can mitigate or prevent future occurrences.

Optimizing Database Queries

If the slow query log revealed specific inefficient queries, work with the plugin/theme developer to optimize them. This might involve adding database indexes, refactoring queries, or caching results.

Caching Strategies

Implementing robust caching is crucial:

  • Page Caching: Use plugins like WP Super Cache, W3 Total Cache, or server-level caching (e.g., Varnish, Nginx FastCGI cache) to serve static HTML versions of pages, reducing database load for most requests.
  • Object Caching: Tools like Redis or Memcached can cache database query results and other objects, significantly speeding up dynamic content generation. Configure WordPress to use these via plugins like Redis Object Cache.
  • AJAX Request Caching: For specific AJAX actions that don’t require real-time data, consider implementing custom caching mechanisms within the plugin or theme itself.

Rate Limiting and Bot Mitigation

If the traffic spike is due to bots or excessive legitimate user activity, consider implementing rate limiting at the web server level.

For Nginx, you can use the limit_req_zone and limit_req directives. This example limits requests to admin-ajax.php from a single IP to 10 per minute:

http {
    # ... other http configurations ...

    # Define a zone for rate limiting based on IP address
    # $binary_remote_addr is the client IP address
    # 10r/min means 10 requests per minute
    # 60 means the burst size is 60 requests (allowing for short bursts)
    limit_req_zone $binary_remote_addr zone=admin_ajax_limit:10m rate=10r/min;

    server {
        # ... other server configurations ...

        location = /wp-admin/admin-ajax.php {
            # Apply the rate limiting zone to this location
            limit_req zone=admin_ajax_limit burst=60 nodelay;

            # ... your existing PHP-FPM or proxy_pass configuration ...
            try_files $uri $uri/ /index.php?$args;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # Adjust PHP version as needed
        }

        # ... other location blocks ...
    }
}

This configuration will return a 503 Service Temporarily Unavailable error to clients exceeding the rate limit. You might need to adjust the `rate` and `burst` parameters based on your site’s normal traffic patterns.

Server Resource Scaling

If the traffic is legitimate and unavoidable, and optimization/caching isn’t sufficient, consider scaling your Linode server resources. This might involve upgrading to a larger instance with more CPU, RAM, or faster storage (e.g., NVMe SSDs). For database-intensive workloads, a dedicated database server or a managed database service can also be a more scalable solution.

Conclusion

Diagnosing cascading database downtime triggered by admin-ajax.php spikes requires a methodical approach, combining web server log analysis, database performance monitoring, and real-time resource observation. By systematically identifying the source of excessive AJAX requests and understanding their impact on the database, you can implement targeted solutions ranging from plugin optimization and caching to server-level rate limiting and resource scaling, ensuring the stability and availability of your WordPress site.

Primary Sidebar

A little about the Author

Having 9+ Years of Experience in Software Development.
Expertised in Php Development, WordPress Custom Theme Development (From scratch using underscores or Genesis Framework or using any blank theme or Premium Theme), Custom Plugin Development. Hands on Experience on 3rd Party Php Extension like Chilkat, nSoftware.

Recent Posts

  • Disaster Recovery 101: Architecting Auto-Failovers for Redis and PHP Deployments on OVH
  • How We Audited a High-Traffic WooCommerce Enterprise Stack on Google Cloud and Mitigated Race conditions during high-concurrency payment processing
  • Disaster Recovery 101: Architecting Auto-Failovers for Elasticsearch and Magento 2 Deployments on DigitalOcean
  • An Auditor’s Checklist for Securing WordPress Backends on OVH
  • Step-by-Step: Diagnosing Perl script high CPU throttling due to unoptimized regular expressions on AWS Servers

Copyright © 2026 · Vinay Vengala