Knowing when something breaks

A website downtime alert in n8n that does not cry wolf

Most small businesses find out their site is down when a customer mentions it. This takes an hour to build, and the retry rule is what stops it becoming the alert you learn to ignore.

Build time
An hour
Difficulty
Beginner
Template
6 nodes

What you need before you start

  • An n8n instance, ideally not on the same server as the site you are checking.
  • Somewhere for the alert to land. Telegram, Slack, ntfy and email all work.
  • The URL of a page that proves the site is genuinely alive, not just the homepage.

Ask a small business how they found out their website was down and the answer is nearly always the same. A customer mentioned it. Usually a day later, usually with an apology in it, as though it were their fault for noticing.

An hour of work fixes that permanently. Most of that hour goes into one decision that most tutorials get wrong.

The mistake that makes monitors useless

The obvious build is: fetch the page, if it fails, send an alert. It works, it takes fifteen minutes, and within a fortnight you are ignoring it.

Because the internet is not reliable at the level of a single request. DNS occasionally takes a second longer than it should. A connection gets dropped between two networks neither of which are yours. None of that means your site is down, and all of it looks identical to your site being down if you only ever ask once.

We hit this on our own monitoring in August 2026. It reported a service down with the message “the operation was aborted due to timeout”. The service was fine on every measure available: no restart, jobs running successfully either side of the failed check, and 121 consecutive probes from inside the machine answering in under two milliseconds. The ten seconds went somewhere between the edge and the origin and left no record at either end.

What was wrong was the monitor, not the server. One sample, no retry, so any hiccup anywhere in the path produced a full outage alert.

The fix is three lines of logic: try, wait a few seconds, try again, and only alert if every attempt fails. A real outage fails all of them and you still hear about it within the same run. A blip resolves on attempt two and gets logged rather than shouted about.

Pick the right URL

Not the homepage, if you can help it.

A homepage is often the most heavily cached page on the site, which means it can keep answering happily while everything behind it is broken. Pick something that touches the parts that matter: a page that reads from the database, a page generated rather than static.

And check for content, not just a status code. A page can return 200 with a stack trace on it, or with an “under maintenance” notice, and both count as up if you only look at the number. Pick a phrase that appears when things are right, your phone number in the footer, or the heading of the page, and check the response actually contains it.

The build, six nodes

1. Schedule Trigger. Every five minutes.

2. Code node, called Probe. The whole retry rule lives here, and n8n’s Code node can make HTTP calls with fetch, so this is one node rather than four:

const url = 'https://yoursite.co.uk/contact/';
const expect = 'Get in touch';
const attempts = [];

for (let i = 0; i < 3; i++) {
  if (i > 0) await new Promise((r) => setTimeout(r, 3000));
  const started = Date.now();
  try {
    const res = await fetch(url, {
      signal: AbortSignal.timeout(10000),
      headers: { 'user-agent': 'LoadOff uptime check' },
    });
    const body = await res.text();
    const ok = res.status === 200 && body.includes(expect);
    attempts.push({ ok, status: res.status, ms: Date.now() - started });
    if (ok) break;
  } catch (err) {
    attempts.push({ ok: false, status: 0, ms: Date.now() - started, error: String(err.message) });
  }
}

const up = attempts.some((a) => a.ok);
return [{ json: {
  up,
  transient: up && attempts.length > 1,
  attempts,
  url,
}}];

Note attempts.some rather than checking only the last one. If attempt one succeeds we break out immediately and never make the other two, so a healthy site costs exactly one request every five minutes.

3. IF node, called Down. Route on up being false.

4. Telegram or Slack. The alert. Include the per-attempt timings from attempts, because “failed three times in ten seconds each” and “failed three times instantly” are different problems and you want to know which before you log in.

5. NoOp, called Transient. The true branch, where transient is set. Do nothing except let the execution record it.

Do not delete this node when you tidy up later. A rising rate of transients is the early warning that something is genuinely degrading, and it is the only cheap signal you get before an outage. Ours has caught a recurring path problem twice.

6. IF node, called Recovered. Optional, and worth it. If the previous state was down and this one is up, send a recovery message. Without it you get told about every outage and never told it ended, and you will go and check by hand every time.

Where to run it

Somewhere other than the thing you are watching.

This sounds obvious written down and it is the single most common flaw in home-built monitoring. A monitor on the same server cannot tell you the server has died, and dying is the failure mode you built it for. Our own site monitoring runs on Cloudflare rather than on the machine it watches, for exactly that reason.

If your n8n runs on the same box as your website, this workflow is still worth building, and it will still catch application errors, a full disk and a crashed service. It will simply be silent on the day the whole machine goes, which is the day you would most like to hear from it.

Two alert channels, not one

Alert email lands in spam more often than people expect. We found this out with a lead notification pipeline: the emails were being sent and delivered and were sitting in a spam folder nobody opened.

An alerting system nobody sees is worse than none, because it produces confidence you have not earned. Send to two independent places, in parallel rather than one after the other, so a failure in one does not stop the other. A phone push and an email covers it.

What it will never catch

That your contact form has stopped delivering.

The page loads. The form renders. Someone fills it in, presses send, and the message goes nowhere, because a credential expired or an inbox rule changed. Every check in this workflow passes throughout.

That is the outage that actually costs money, and finding it needs something that tests the whole path rather than the page. The heartbeat build is the general version of that idea, and it is the one we would build second.

Published 28 August 2026. Written by the people who run this sort of thing for clients, on n8n, including our own lead pipeline.

Next in knowing when something breaks: The certificate and domain expiry alert. Or go back to all 4 in this category.

Questions about this build

How often should a downtime check run?

Every five minutes is the sensible default. It catches a real outage fast enough to act on and does not hammer your own server. Every minute buys you four minutes of warning and quadruples the chance of a false alarm, which is a bad trade for a business site.

Why alert after two failures rather than one?

Because a single failed request over the public internet cannot tell an outage from a transient stall. We learned this on our own monitor: it paged a full outage alert for a service that was provably healthy, having spent ten seconds somewhere between the edge and the origin and left no trace at either end. It now needs three failed attempts before it says anything, and a real outage still fails all three within the same run.

Should the monitor run on the same server as the site?

No, and this is the mistake that makes the whole thing pointless. A monitor on the box it is watching cannot report that the box has died, which is the failure you most want to know about. Put it somewhere else, even a free tier somewhere, and accept that it is a different machine.

Is a 200 response enough to know the site works?

It proves a page answered. It does not prove your contact form still delivers, your checkout works, or the page is showing anything but an error message with a 200 status. Check for a specific string in the response as well as the status, and pick a page that touches something real.

Do I need Uptime Kuma or a paid monitor instead?

Those are good and if you already run one, use it. Build this when you want the alert to go somewhere specific, want it in the same place as your other automations, or want to check something a generic monitor cannot express. The logic is an hour's work either way.

The next step

Stop losing leads.Let's fix it this week.

Tell us what keeps slipping and we'll scope something around it. You'll be talking to Max, who runs the work, not a sales team. Most clients are live within 48–72 hours of that first conversation.

30-day rolling retainers. No lock-in. Cancel anytime.