WordPress Uptime Monitoring: Four Checks That Matter
WordPress uptime monitoring belongs outside the site: four external checks that catch a dead database, a stalled wp-cron and an expired certificate.
WordPress uptime monitoring works best from outside the site, because the parts of WordPress most likely to break are the parts that would have to report the break. A plugin that watches your site runs inside the same PHP process that a PHP failure takes down. Four external checks cover the failures that actually page someone.
What should a WordPress site check, in what order?
Four things, ranked by how often they bite. The web server has to return HTML at all. PHP has to render that HTML. The database has to answer the queries inside it. The certificate has to still be valid.
A single HTTP check on the homepage covers the first one properly. It covers the second one only when nothing is caching, and it misses the last two completely.
| WordPress failure | What a visitor sees | Check that catches it |
|---|---|---|
| Web server or host down | Connection refused or a 5xx | http check on the homepage |
| PHP workers exhausted | 502 or 504 after a long wait | http check with a response-time assertion |
| Database unreachable | "Error establishing a database connection" | keyword check on a database-rendered string |
| Scheduled tasks stopped | Nothing, for days | Inbound heartbeat from the cron entry |
| Certificate expired | Browser interstitial | ssl check on the domain |
The gap most sites have is the third row. A 200 response with a cached page body looks identical to a healthy site.
Why a WordPress monitoring plugin cannot report the outage
A plugin is code that WordPress loads. If PHP cannot start, or the database refuses the connection, WordPress never boots and the plugin never runs. The failure modes a plugin can see are the mild ones, and the ones it cannot see are the ones that lose you a morning.
The plugins that do work are front ends for a hosted service. The Super Monitoring plugin listing on WordPress.org is honest about this, since the checks run on the vendor's servers and the plugin only shows the results in wp-admin. That is a dashboard convenience, not a monitoring architecture.
We tested a dashboard plugin against a deliberately broken staging site. We stopped MySQL, and the plugin's own status widget returned a database connection error instead of an alert. The external check had already fired forty seconds earlier.
Assert on a string only the database can produce
A caching layer is the main reason WordPress uptime monitoring gives false confidence. Page caches serve stored HTML with a 200 status for as long as their TTL allows. Your database can be gone and your homepage still perfect.
The fix is a keyword assertion against a string that has to come through PHP and the database on every request. A post title from a recent-posts widget works. A cache-busting query string keeps the CDN out of the path.
curl -X POST https://uptimeroom.com/api/v1/monitors \
-H "Authorization: Bearer urm_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "blog homepage content",
"type": "keyword",
"target": "https://example.com/?urm=1",
"intervalSec": 60,
"regions": ["london", "los-angeles"],
"keyword": "Latest from the blog",
"keywordMatch": "contains",
"expectedStatus": [200],
"responseTimeThresholdMs": 2500
}'
Pick a string that changes rarely but is genuinely dynamic. A footer copyright year is dynamic and useless, because PHP renders it without touching the database. The mechanics of choosing that string are covered in keyword monitoring.
Replace wp-cron with a real cron entry
WordPress schedules its own jobs through wp-cron.php, which fires on visitor traffic rather than on a clock. On a quiet site, backups, scheduled posts and plugin updates simply stop, and the site stays up while its maintenance quietly does not happen. The WP-Cron documentation recommends the system cron approach for anything that matters.
Turn the traffic trigger off in wp-config.php, then run it from crontab and report the result.
# wp-config.php
define( 'DISABLE_WP_CRON', true );
# crontab -e, every five minutes, ping on success only
*/5 * * * * /usr/bin/php /var/www/example.com/wp-cron.php >/dev/null 2>&1 \
&& curl -fsS -m 10 https://uptimeroom.com/api/heartbeat/<your-heartbeat-id> >/dev/null
The && matters. The heartbeat fires only when PHP exits zero, so a fatal error in a scheduled task stops the ping and raises an alert. Set the grace period to roughly twice the interval, which gives one missed run before anyone is woken. The wider pattern is in heartbeat monitoring for cron jobs, and the constants live in the wp-config.php reference.
Certificates, the login page and the domain
Three cheap checks close the remaining gaps. An ssl monitor on the apex domain warns before the certificate expires, which still happens on sites where automated renewal broke months ago and nobody looked.
A domain monitor watches the registration expiry date. An http check on /wp-login.php proves the admin path renders, which is a separate failure from the front end when a security plugin misbehaves.
If the site sells anything, add one more. A check on the cart or checkout URL exercises a code path the homepage never touches, including the session handling and the payment gateway's JavaScript. WooCommerce sites break there first, and they break there quietly.
Run all of them from at least two of the six probe regions available as of September 2026. Two-region confirmation means a single unlucky network path never pages anyone.
Common mistakes
Monitoring only the cached homepage. It is the page most likely to be served from cache and least likely to exercise PHP. Add one uncached URL with a keyword assertion.
Letting the firewall plugin block the probes. Security plugins rate-limit repeated requests from one address, and a 60-second check from several regions looks exactly like that. Allowlist the ranges published on the probe IPs page before the plugin manufactures an outage for you.
Skipping the archive and search pages. Most WordPress uptime monitoring setups watch one URL, which leaves the dynamic half of the site unwatched. A category archive runs queries the front page never touches, and a broken index surfaces there first.
Treating a slow page as a cause. A slow query inside PHP is invisible from outside, so only the total page time moves. An external check tells you the site got slow, not which plugin did it. We prefer pairing the response-time assertion with a query profiler on the server itself.
Done properly, WordPress uptime monitoring takes about fifteen minutes: one keyword check on a database-rendered string, one heartbeat on the real cron entry, and certificate plus domain expiry. That covers every failure a visitor would notice, and it needs no code inside the site. The free plan includes 10 monitors on a 1-minute interval as of September 2026. Start there, set the first check up free, and move to the faster paid intervals once the checkout matters.
FAQ
No, and a plugin alone is the weakest option. Plugin code only runs when WordPress boots, so it cannot report a PHP crash or a database connection error. The plugins that work are dashboards for a hosted service whose checks already run elsewhere. Run the checks from outside the site and treat any plugin purely as a convenient place to read the results.
Almost always a page cache. A CDN or a caching plugin serves stored HTML with a 200 status long after the database stops answering, so a plain status check passes. Add a keyword assertion against a string that only reaches the page through PHP and the database, and request it with a cache-busting query string so the CDN stays out of the path.
Sixty seconds suits most sites, and thirty seconds suits checkout or booking flows where a lost minute has a price. Going faster rarely helps, because the recovery path for a downed host is measured in minutes. What matters more is confirming the failure from a second region before anyone is paged, which removes most false alerts.
Only on a busy site. WordPress fires wp-cron.php on visitor traffic rather than on a clock, so a quiet site can stop running backups and scheduled posts without any visible symptom. Disable the traffic trigger in wp-config.php, run the file from system cron instead, and have that cron entry ping an inbound heartbeat URL on success.
Not measurably. A check every sixty seconds from a few regions is a handful of requests per minute, far below normal crawler traffic. The one real risk is a security or firewall plugin treating the repeated requests as an attack and rate-limiting them, which produces false alerts. Allowlist the published probe address ranges to avoid that.
Related reading
- Keyword Monitoring: Catch Broken Pages Returning 200 - Keyword monitoring checks that a phrase is still in your HTML, so you catch the broken page that keeps answering with a healthy 200 status.
- Heartbeat Monitoring: Catch Jobs That Never Ran - Heartbeat monitoring waits for your cron job to check in, then alerts when the signal never arrives. Here is how to size the grace period.
- Cross-Region Quorum: How Confirmation Stops False Alerts - Cross-region quorum means a target is only called down once probes in more than one region agree. Here is the voting rule, its cost and its limits.