# Log Pages That Run Too Many Database Queries

> Records front-end URLs that run more database queries than a limit you set, with the query count and load time, and lists the worst offenders under Tools > Heavy Pages.

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

## Code

```php
// Pages above this many queries are logged.
$wpide_query_limit = 150;

add_action( 'shutdown', function () use ( $wpide_query_limit ) {
    if ( is_admin() || wp_doing_ajax() || wp_doing_cron() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
        return;
    }

    $count = get_num_queries();

    if ( $count < $wpide_query_limit || empty( $_SERVER['REQUEST_URI'] ) ) {
        return;
    }

    $log   = (array) get_option( 'wpide_heavy_pages', array() );
    $url   = esc_url_raw( home_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
    $log[ md5( $url ) ] = array(
        'url'     => $url,
        'queries' => $count,
        'time'    => round( timer_float(), 3 ),
        'user'    => is_user_logged_in(),
        'when'    => time(),
    );

    update_option( 'wpide_heavy_pages', array_slice( $log, -100, null, true ), false );
}, 999 );

add_action( 'admin_menu', function () use ( $wpide_query_limit ) {
    add_management_page( 'Heavy Pages', 'Heavy Pages', 'manage_options', 'wpide-heavy-pages', function () use ( $wpide_query_limit ) {
        if ( isset( $_POST['wpide_heavy_clear'] ) && check_admin_referer( 'wpide_heavy_clear' ) ) {
            delete_option( 'wpide_heavy_pages' );
        }

        $log = (array) get_option( 'wpide_heavy_pages', array() );
        uasort( $log, function ( $a, $b ) {
            return $b['queries'] <=> $a['queries'];
        } );

        echo '<div class="wrap"><h1>Heavy Pages</h1><p>' . esc_html( sprintf( 'Front-end pages that ran more than %d database queries.', $wpide_query_limit ) ) . '</p>';
        echo '<table class="widefat striped"><thead><tr><th>URL</th><th>Queries</th><th>Load time</th><th>Logged in</th><th>Last seen</th></tr></thead><tbody>';
        if ( ! $log ) {
            echo '<tr><td colspan="5">Nothing logged yet.</td></tr>';
        }
        foreach ( $log as $row ) {
            printf( '<tr><td><a href="%1$s">%2$s</a></td><td>%3$d</td><td>%4$ss</td><td>%5$s</td><td>%6$s</td></tr>', esc_url( $row['url'] ), esc_html( $row['url'] ), (int) $row['queries'], esc_html( $row['time'] ), $row['user'] ? 'yes' : 'no', esc_html( human_time_diff( (int) $row['when'] ) . ' ago' ) );
        }
        echo '</tbody></table><form method="post">';
        wp_nonce_field( 'wpide_heavy_clear' );
        submit_button( 'Clear log', 'secondary', 'wpide_heavy_clear' );
        echo '</form></div>';
    } );
} );
```

## Notes

Keeps the 100 most recent heavy pages in one option; nothing is logged for admin, AJAX, REST or cron requests.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Log Pages That Run Too Many Database Queries" 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/
