Load the WordPress dashboard on any client site. The Site Health Status widget sits there with a green circle and the word "Good", then hedges immediately: your site's health is looking good, but there are still some things you can do. Underneath, three flagged rows. You should remove inactive plugins. You should remove inactive themes. Your site is set to display errors to site visitors.
Every article about this treats it as clutter to be swept away. I want to make a different argument: it is a performance problem, and the standard fix for it does not fix it.
Start with what the widget actually does. It is not rendering a cached score from an option. Loading the dashboard kicks off a set of async tests over the REST API, and among them is the loopback test, which asks WordPress to make an HTTP request to its own URL and wait for the response. Think about that on a shared host with a small pool of PHP workers. The request that is meant to test your site is queued behind, and competing with, the request that is trying to render the page you are staring at.
Then there is the bit almost nobody knows about. Core registers a weekly cron event, wp_site_health_scheduled_check, which runs the whole suite again in the background. It is on every site you have ever built. You have never seen it in a profiler because you have never looked.
Now the answers you get when you search for this.
Answer one, and it is the top result nearly everywhere: Dashboard → Screen Options → untick "Site Health Status".
That is a per-user preference. It is written to user meta. It hides the widget for the exact one person who clicked it, which is the author of the tutorial. Your client logs in and sees the whole panel, unchanged. As an answer to the question people are actually asking, which is almost always "how do I get this off my client's screen", it is wrong, and it has been the top answer for years.
Answer two, the snippet:
add_action('wp_dashboard_setup', function () {
remove_meta_box('dashboard_site_health', 'dashboard', 'normal');
});
This one is real. The widget is gone, for every user. And it has stopped nothing. The cron is still scheduled. The tests still exist. You have hidden the readout, not the work. If you came here because the dashboard was slow, it is still slow, and you now think you fixed it, which is worse than knowing you didn't.
The Tools page is a third path. It never came from the widget, so it survives both of the above:
add_action('admin_menu', function () {
remove_submenu_page('tools.php', 'site-health.php');
}, 99);
Worth being precise: that removes the menu item, not the page. Anyone who types /wp-admin/site-health.php still gets it. If you actually need it locked, gate on capability rather than hiding the link.
And the fourth path is the only one that stops the checks happening at all, the test registry itself plus the weekly event:
add_filter('site_status_tests', function ($tests) {
$tests['direct'] = [];
$tests['async'] = [];
return $tests;
});
add_action('init', function () {
$timestamp = wp_next_scheduled('wp_site_health_scheduled_check');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wp_site_health_scheduled_check');
}
});
Four hooks, four code paths, one feature. Every guide I read covers one. A couple cover two. None cover four, and the difference between the widget being hidden and the checks being off is the entire question.
What I will not do, and what people keep suggesting in the forum threads:
define('DISABLE_WP_CRON', true); // to stop the weekly health check
// or: unhooking the REST API // to stop the async tests
Killing WP-Cron to silence one weekly event takes scheduled posts, backups and update checks with it. Killing the REST API to stop the async tests takes the block editor with it. Both are amputations to treat a rash. If you find either in a client site, ask why.
I tested the settings-panel version with WP Adminify Pro. 25 second demo below.
What Site Health actually costs on a client site:
- Async REST tests on every dashboard load, one of which makes the server call itself and wait
- A weekly cron running the whole suite in the background, unnoticed and unattributed
- A red-flagged security warning about
display_errorsshown to a person with no ability to act on it - The most common "fix" for it, Screen Options, is per-user and does nothing for the person who was actually meant to stop seeing it
What changed after ticking Site Health in Adminify Pro's Hide Admin Notices:
- One option under Productivity → Hide Admin Notices → Other Notices covers the widget for every admin at once
- The Tools → Site Health page goes with it, no separate
remove_submenu_pageto remember - The checks stop, which is the part
remove_meta_boxnever did - The same module handles the update notice pile-up, so the dashboard opens to work rather than a stack of banners
- Nothing to re-paste after a migration, and it survives core updates
The caveat I will not skip: disabling Site Health does not make your site healthy. It is the only thing on a stock install that will tell you your PHP is unsupported, your HTTPS is misconfigured, a required module is missing, or background updates have quietly stopped. Turning it off means nobody will ever hear those things again. That is right when you are monitoring them elsewhere, from a maintenance report, an uptime monitor, a staging pipeline, and it is wrong on a site nobody maintains, where that panel is the only warning system that exists.
And the option that should be the top answer and isn't: WordPress ships a capability, view_site_health_checks. Filter it away from every role except yours and Site Health stays fully alive for you while the client never sees it. When someone asks how to remove Site Health, that is very often the thing they actually wanted, and it is not on page one for any of these queries.
Step-by-step doc: https://wpadminify.com/docs/adminify/productivity/hide-admin-notices
How do you handle Site Health on sites you maintain for other people: filter site_status_tests, gate it behind view_site_health_checks, disable it with a plugin, or leave it and field the phone calls?
Top comments (0)