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.
Opens WPIDE on
Code
// 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 add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.