What a status page is for
A status page exists to answer one question fast: “is the service working right now?”
Secondary questions:
- “Is this a known issue?”
- “When did it start?”
- “What’s the ETA on a fix?”
- “Has this happened before?”
A good status page answers the first question in 1 second and the rest within 10 seconds of clicking around. Everything else is decoration.
The bar is lower than people think. Even a static HTML page that says “All systems operational” updated by hand is dramatically better than no status page at all, because it gives customers somewhere to look that isn’t your support inbox.
In-house vs. hosted: the honest tradeoffs
Hosted status pages (Statuspage by Atlassian, BetterStack, Statuspal, Hund, Instatus) handle the entire surface for you. You get a dashboard, automated incident messaging, subscriber notifications via email/SMS/Slack, a clean URL like status.yourcompany.com, and historical uptime tracking.
- Cost: $30–$500/month depending on tier and subscriber count
- Time to set up: 30 minutes
- Maintenance: near zero
Self-hosted status pages can be:
-
A static page (HTML, generated nightly from monitoring data)
-
A small app you build (Express, Rails, Next.js — pull data from your monitoring API)
-
An open-source tool (Cachet, Statping, Uptime Kuma’s status page mode, Vrok)
-
Cost: Hosting only (often $0–$20/month)
-
Time to set up: 2–20 hours depending on approach
-
Maintenance: ongoing
The right choice depends mostly on whether you have subscribers — people who want to be notified when an incident is declared.
The subscriber notification problem
If your customers don’t want to get notified when there’s an outage, a static page is fine. You update it during incidents (or generate it from monitoring data), and customers check it when they suspect something’s broken.
If your customers do want notifications — and most B2B SaaS customers expect this — you need infrastructure: email delivery at scale, SMS routing, possibly Slack/webhook integrations, subscriber management (opt-in/opt-out, GDPR, double-confirm), and reliability so notifications go out during an outage (which is exactly when your own infrastructure might be unreliable).
Hosted services solve this for you. Self-hosted means you’re building or integrating it. For most teams, the math says hosted is worth it the moment you have more than a handful of subscribers.
When self-hosted makes sense
The case for building it yourself:
- No subscriber notifications needed. Pure status display, occasionally updated.
- You want a specific design that hosted services don’t allow.
- You want it tightly integrated with your existing systems — incident channels, deploy pipelines, custom event types.
- You’re cost-sensitive and have engineering time to spend.
- You’re already running good monitoring and just need to surface it publicly.
A static-generation approach works well for most of these. You run a script every minute that queries your monitoring system, computes “are all systems green?”, and rewrites a small HTML file. Stick it on a CDN. Done.
A minimal in-house status page
Here’s the bones of a Node.js service that pulls from a monitoring system and serves a status page:
const express = require('express');
const app = express();
app.get('/status', async (req, res) => {
const monitors = await fetchMonitors();
const overallStatus = monitors.every(m => m.status === 'up')
? 'operational'
: 'degraded';
res.render('status', {
overallStatus,
monitors,
lastUpdated: new Date()
});
});
async function fetchMonitors() {
// Call your monitoring service's API
return [
{ name: 'Web app', status: 'up', uptime30d: 99.98 },
{ name: 'API', status: 'up', uptime30d: 99.95 },
{ name: 'Background', status: 'up', uptime30d: 99.99 }
];
}
That’s the basic version. To make it useful you add:
- Cache the API response for 30–60 seconds so the page doesn’t hammer your monitoring API
- Add incident management — a table that lets you manually post current incidents
- Add historical uptime charts — daily uptime % over the past 90 days
- Add an RSS or JSON feed so external tools can subscribe
The whole thing is a few hundred lines of code. The hard part isn’t the page — it’s the discipline of keeping it updated during incidents.
The “host it elsewhere” rule
The most important thing about a status page: don’t host it on the same infrastructure as the thing you’re monitoring.
If your status page is on the same cloud provider, behind the same DNS, going through the same CDN as your main app — then when the main app goes down, the status page usually goes down with it. Customers can’t find out what’s broken because the status page is broken too.
Hosted status page services solve this by being on entirely separate infrastructure. If you self-host, the rule is to put the status page somewhere else — a different cloud, a static CDN, or even just a $5 VPS with no other purpose. Cost is negligible; the independence is invaluable.
Open-source self-hosted options
If you want a richer setup than rolling your own from scratch, but want to keep it self-hosted, the open-source landscape has options:
- Statping-ng — Go-based, easy to deploy, includes notifications and an admin UI
- Cachet — PHP/Laravel, mature, more configuration overhead
- Uptime Kuma — primarily a monitor, but its status pages mode is decent
- Vrok — newer, Rust-based, lightweight
All of these need ongoing maintenance — security patches, dependency updates, monitoring of the status page itself. Free in dollars, not free in time.
What to put on the page
The bare minimum for a useful status page:
- Overall status indicator — a big colored badge: “All systems operational,” “Some systems degraded,” “Major outage”
- Component breakdown — each major service or feature, with its current status
- Current incidents — anything ongoing, with first-posted time and last update
- Recent incidents — last 5–10 incidents, even if resolved
- Historical uptime — a 90-day calendar grid or simple percentage
Optional but useful:
- Scheduled maintenance — upcoming windows where you’ll be intentionally down
- Subscribe to updates — email, RSS, Slack webhook, SMS
- Per-region status — useful if you have customers in different geographies
- Performance graphs — response time over time
Things that make status pages worse:
- Too much detail. Customers don’t need to know about every microservice. Group things into customer-facing categories.
- Stale information. A page that hasn’t updated in 6 hours is worse than no page — it signals you’ve forgotten about the outage.
- Self-congratulatory uptime stats. “99.999% uptime over 90 days!” looks dishonest when there’s a current outage. Just show the data.
Automating incident posts
The single biggest improvement most teams can make is automating incident posts from monitoring alerts.
The flow:
- Monitoring detects an outage and creates an alert
- A webhook fires that auto-creates an incident on the status page
- Customers subscribed to status updates get notified
- When monitoring sees the outage clear, a corresponding webhook fires to mark the incident resolved
Most hosted status page services have native integrations for this. Self-hosted requires you to wire it up — usually a small webhook handler that translates monitoring events into status page incidents.
The benefit is the status page stays updated even when the human running it is busy fixing the outage. Customers see “we detected an issue at 14:42” within seconds of the actual problem starting.
My honest recommendation
For most teams:
- Sub-100 customers, no subscriber notifications needed: Static page or open-source self-hosted. Update manually. Spend the saved money on better monitoring.
- 100+ customers expecting notifications: Use a hosted service. The maintenance burden of building this in-house outweighs the cost.
- Enterprise with specific compliance needs: Often pushes back toward self-hosted, with the budget to do it right.
The status page itself is rarely the hard part. The hard part is the operational discipline to keep it updated during real incidents. Hosted services help here by lowering the friction of posting an update — and friction matters when you’re already firefighting.
For monitoring data that drives whatever status page you choose, MyUptimeBot exposes results via webhooks and API. Self-hosters can pipe our results into their own page. Hosted-service users can wire our alerts into Statuspage / Statuspal / BetterStack via standard integrations.
The status page isn’t the monitoring system — it’s the public face of the monitoring system. Pick the cheapest approach that fits your customer expectations, and put the saved energy into the monitoring itself.