A homepage is the least representative page a service has. It is usually static, aggressively cached at the edge, and served without touching a database. It will happily keep loading for hours after everything behind it has stopped working.
Why the front door stays up ¶
Modern architecture separates the cheap from the expensive on purpose:
- Marketing pages are pre-rendered and served from a CDN edge node near you. No origin server is involved at all once they are cached.
- Checkout, login, search and any personalised view must reach the origin, the database, and usually several internal services.
- Images and static assets often live on a different hostname with its own availability.
So when the database is unreachable, the homepage is served from cache and looks perfect while every meaningful action returns a 503. The page is not lying. It is answering a question nobody asked.
Six partial failures worth recognising ¶
- Checkout fails, browsing works. Payment provider, or the order service. Often a third party the vendor does not control and will not mention.
- Login fails, everything else works. Authentication. See site versus login versus app outages.
- Images missing, layout intact. A separate asset host or object storage. Cosmetic until it is a product catalogue.
- Search returns nothing. Search indexes are usually a separate cluster and fail independently. Empty results look like a valid answer, which is what makes this one so slow to detect.
- Everything works but is slow. Degradation, not outage. A retrying dependency, a saturated pool, a cache that lost its contents.
- Writes fail, reads work. A read replica serving traffic while the primary is unavailable. Uniquely nasty, because everything looks fine until someone tries to save.
What to check instead of the homepage ¶
Two changes make a check meaningful:
Check the endpoint that matters. If you depend on an API, check the API hostname, not the marketing site. They are frequently different deployments with different availability. Our checker accepts any hostname.
Assert on content, not just status. A 200 proves something answered. It does not prove the answer was right. A page that renders an error message inside a successful response is invisible to a status-code check and obvious to one that looks for an expected string. This is what keyword assertions on a monitor are for, and it is the single highest-value upgrade to a naive check.
Reading a partial outage from the browser ¶
Developer tools, Network tab, reload, then sort by status. You are looking for:
- 5xx responses against a specific hostname while others are 200.
- Requests that never complete while the rest of the page finishes.
- A 200 whose response body contains an error rather than data.
Whichever hostname owns the failures is the component that is down, and it is the one worth naming in a report or pointing a monitor at.
Why this matters for monitoring generally ¶
Most uptime monitoring measures the cheapest possible thing and reports it as service health, because the cheapest thing is easy to check and almost always green. That produces a comfortable dashboard and a support queue full of people who cannot use the product. A check is worth exactly as much as the assumption behind it: that the thing measured is the thing users depend on.
Why status-code monitoring misses all of this ¶
A status code describes the transaction, not the answer. Every one of these is a 200:
- A page that rendered an error message where the content should be.
- A search result set that is empty because the index is unreachable.
- A cached copy of a page served long after the origin stopped responding.
- A maintenance page, unless somebody remembered to give it a 503.
That last one is worth dwelling on. A maintenance page served with a 200 tells every monitoring system in the world that the site is healthy. It is one of the most common ways an outage goes undetected, and it is a one-line fix on the server that almost nobody makes.
Choosing what to check ¶
Three questions, in order:
- What breaks your day if it stops? Monitor that hostname, not the one on the business card.
- What does a healthy response contain? Pick a short string that only appears when the backend actually answered, and assert on it. A product name in the page chrome is a poor choice because it survives most failures; a price, a record count, or a timestamp is a good one.
- How long is too long? A response that takes 30 seconds is a failure to a user regardless of its status code. Latency belongs in the definition of "up".
Our checker takes any hostname, so you can point it at an API host directly and compare its behaviour to the front door. When the two disagree, you have found a partial outage, which is exactly the case the front door was never going to reveal.
Reporting one usefully ¶
Name the hostname and the failing request rather than the product. "Checkout is broken" starts a conversation; "POST to api.example.com/v2/orders returns 503, browsing is fine, started 14:20 UTC" starts a fix.