DEV Community

Vigilmon
Vigilmon

Posted on

How to monitor your Node.js app with uptime checks and heartbeat monitoring (free with Vigilmon)

The problem: your Node.js app fails silently

You've deployed your Node.js app. CI is green. You go to sleep.

At 2am, your Express server crashes. A database connection pool exhausts. Your cron job that sends daily summaries starts silently failing. Nobody notices for three days.

Sound familiar? This is the silent failure problem that haunts production Node.js apps — and it's surprisingly easy to fix with two types of monitoring.

Two monitors every Node.js app needs

1. HTTP uptime monitoring

Your app exposes a /health endpoint. A monitoring service hits it every 60 seconds from multiple regions. If it goes down, you get alerted immediately.

2. Heartbeat monitoring (dead man's switch for cron jobs)

Your cron job tells the monitoring service it ran successfully. If the ping stops arriving, you get alerted.

This inverted approach catches silent failures that traditional monitoring completely misses.

Step 1: Add a health endpoint to Express

Start with a basic health check:

const express = require('express');
const app = express();

app.get('/health', (req, res) => {
  res.json({
    status: 'ok',
    timestamp: new Date().toISOString(),
    uptime: process.uptime()
  });
});

app.listen(3000);
Enter fullscreen mode Exit fullscreen mode

For production, check your database connection too:

const { Pool } = require('pg');
const pool = new Pool({ connectionString: process.env.DATABASE_URL });

app.get('/health', async (req, res) => {
  try {
    await pool.query('SELECT 1');
    res.json({ status: 'ok', db: 'connected', uptime: process.uptime() });
  } catch (err) {
    res.status(503).json({ status: 'error', db: 'disconnected' });
  }
});
Enter fullscreen mode Exit fullscreen mode

A 503 on your /health route means the monitoring service will alert you the moment the DB connection drops — not three hours later when users start complaining.

Step 2: Set up HTTP monitoring with Vigilmon

Vigilmon is a free, open-source uptime monitor that uses multi-region probes (Africa, UK, US-East). Unlike single-probe services, it only alerts when a majority of probes agree the site is down — eliminating 3am false positives from transient network blips.

Create your first monitor:

  1. Sign up at app.vigilmon.online — free tier, no credit card
  2. Click Add Monitor → HTTP
  3. Enter your URL: https://your-app.example.com/health
  4. Set check interval: 60 seconds
  5. Expected status code: 200

That's it. If your /health endpoint returns a non-200 status or times out, Vigilmon notifies you within 2–3 minutes.

Step 3: Set up heartbeat monitoring for your cron jobs

Heartbeat monitoring catches what HTTP monitoring can't: a cron job that stops running.

Create a Heartbeat monitor in Vigilmon:

  1. Click Add Monitor → Heartbeat
  2. Set the expected interval: 24 hours (or whatever your job's cadence is)
  3. Copy the generated ping URL: https://app.vigilmon.online/api/heartbeats/ping/YOUR_TOKEN

Add the ping to your Node.js cron job:

Using node-cron:

const cron = require('node-cron');

cron.schedule('0 0 * * *', async () => {
  try {
    // Your actual job logic
    await runDailyBackup();
    await syncUserData();

    // Only ping if the job completed successfully
    await fetch('https://app.vigilmon.online/api/heartbeats/ping/YOUR_TOKEN');

    console.log('Daily job completed');
  } catch (err) {
    console.error('Daily job failed:', err);
    // No ping = Vigilmon alerts you when the interval expires
  }
});
Enter fullscreen mode Exit fullscreen mode

Using node-schedule:

const schedule = require('node-schedule');

const job = schedule.scheduleJob('0 0 * * *', async function() {
  try {
    await processNightlyReport();
    await fetch('https://app.vigilmon.online/api/heartbeats/ping/YOUR_TOKEN');
  } catch (err) {
    console.error('Nightly report failed:', err);
    // Vigilmon detects the missing ping and alerts you
  }
});
Enter fullscreen mode Exit fullscreen mode

The key insight: only ping on success. If your job throws, the ping never fires. When Vigilmon doesn't receive a ping within the expected window, you get alerted — even if the job is failing silently with no errors logged anywhere.

Step 4: Configure Slack and email alerts

In Vigilmon's notification settings, you can wire up:

Email: Alerts go to your registered email when any monitor goes down or a heartbeat goes missing.

Slack webhook:

  1. Create an Incoming Webhook in your Slack workspace (Apps → Incoming Webhooks)
  2. In Vigilmon, go to Settings → Notifications → Slack
  3. Paste the webhook URL
  4. Choose which monitors trigger Slack alerts

Your #ops channel will receive a message the moment something breaks — no manual checking required.

Custom webhooks: Vigilmon can POST to any URL with the monitor status, timestamps, and probe details. Use this to integrate with PagerDuty, OpsGenie, or any alerting pipeline.

What this setup catches

Failure scenario Detection method
Express server crashes or OOM killed HTTP monitor on /health
Database connection pool exhausted /health returns 503
Cron job throws an unhandled error Heartbeat goes missing
Cron job stops running (scheduler bug) Heartbeat goes missing
Slow responses / degraded performance Response time history + P50/P95 charts
SSL certificate about to expire SSL expiry monitor (warns 30 days out)

Self-hosting option

Vigilmon is fully open-source (MIT). If you need to keep monitoring on-premise or want to customize it:

git clone https://github.com/isak-ialogics/vigil
cd vigil
cp .env.example .env
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Stack: Laravel 12 / PHP 8.4, PostgreSQL + TimescaleDB for time-series data, FrankenPHP.

Summary

Two monitors. One for your HTTP endpoint, one for each scheduled job. That's the minimum to have real production visibility for a Node.js app.

Free tier on Vigilmon includes:

  • Up to 5 monitors
  • 60-second check intervals
  • Multi-region probes (no single point of failure)
  • Email and Slack alerts
  • Response time history with P50/P95 charts

Get started: app.vigilmon.online
Self-host: github.com/isak-ialogics/vigil

Top comments (1)

Collapse
 
vigilmon profile image
Vigilmon

If you're running your Node.js app in Docker, check out our follow-up article: How to Monitor Docker Containers with Vigilmon (HTTP, TCP, and Alerts) — covers health check endpoints, TCP port monitoring, webhook alerts, and a public status page for containerized services.