# Find What Is Calling admin-ajax.php

> Counts admin-ajax.php requests per action (and whether they come from the front end or the dashboard) for the current day and the previous six, and shows the busiest ones under Tools > AJAX Usage.

- Type: PHP
- Runs: Run everywhere
- Category: [Performance](https://wpide.com/library/category/performance/)
- Tags: ajax, monitoring, debugging
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/perf-admin-ajax-usage-log/

## Code

```php
add_action( 'admin_init', function () {
    if ( ! wp_doing_ajax() || empty( $_REQUEST['action'] ) ) {
        return;
    }

    $action = substr( sanitize_key( wp_unslash( $_REQUEST['action'] ) ), 0, 60 );
    $from   = ( isset( $_SERVER['HTTP_REFERER'] ) && false !== strpos( (string) wp_unslash( $_SERVER['HTTP_REFERER'] ), '/wp-admin/' ) ) ? 'admin' : 'front';

    add_action( 'shutdown', function () use ( $action, $from ) {
        $day = gmdate( 'Ymd' );
        $log = (array) get_option( 'wpide_ajax_usage', array() );
        $key = $action . '|' . $from;

        $log[ $day ][ $key ] = ( isset( $log[ $day ][ $key ] ) ? (int) $log[ $day ][ $key ] : 0 ) + 1;
        krsort( $log );
        update_option( 'wpide_ajax_usage', array_slice( $log, 0, 7, true ), false );
    } );
}, 0 );

add_action( 'admin_menu', function () {
    add_management_page( 'AJAX Usage', 'AJAX Usage', 'manage_options', 'wpide-ajax-usage', function () {
        $totals = array();
        foreach ( (array) get_option( 'wpide_ajax_usage', array() ) as $day ) {
            foreach ( $day as $key => $count ) {
                $totals[ $key ] = ( isset( $totals[ $key ] ) ? $totals[ $key ] : 0 ) + (int) $count;
            }
        }
        arsort( $totals );

        echo '<div class="wrap"><h1>AJAX Usage (last 7 days)</h1><table class="widefat striped" style="max-width:720px"><thead><tr><th>Action</th><th>Called from</th><th>Requests</th></tr></thead><tbody>';
        if ( ! $totals ) {
            echo '<tr><td colspan="3">No AJAX requests recorded yet.</td></tr>';
        }
        foreach ( array_slice( $totals, 0, 50, true ) as $key => $count ) {
            list( $action, $from ) = explode( '|', $key );
            printf( '<tr><td><code>%s</code></td><td>%s</td><td>%s</td></tr>', esc_html( $action ), esc_html( $from ), esc_html( number_format_i18n( $count ) ) );
        }
        echo '</tbody></table><p class="description">"heartbeat" is the WordPress Heartbeat API; high front-end counts usually come from plugins polling for updates.</p></div>';
    } );
} );
```

## Notes

Counts are batched in memory and written once per request; deactivate the snippet when you have found the culprit.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Find What Is Calling admin-ajax.php" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
