tutorial

Monitoring Your Render.com Application with Vigilmon

Add external uptime monitoring to apps on Render — health endpoints, Vigilmon ping monitors, and alerts for cold starts, spin-downs, and real outages.

Monitoring Your Render.com Application with Vigilmon

Render is a popular Heroku alternative that handles build, deploy, and TLS automatically. But like Heroku before it, free and starter-tier Render services spin down after inactivity — and when a real outage hits, Render's internal dashboards don't page you.

You need external monitoring: something that probes your live URL from outside Render's infrastructure, knows the difference between a cold start and a crash, and wakes you up when something actually breaks.

This tutorial covers:

  • A health endpoint for Render web services
  • Vigilmon HTTP monitoring with cold-start tolerance
  • Alerts that don't false-fire on every spin-up
  • Heartbeat monitoring for Render cron jobs

Step 1: Add a health endpoint to your app

Every Render web service needs a /health route that returns 200 when the app is running correctly and 503 when something is wrong.

Node.js / Express:

// server.js
import express from 'express';

const app = express();

app.get('/health', async (req, res) => {
  try {
    // optional: check DB or cache connectivity here
    res.json({
      status: 'ok',
      env: process.env.RENDER_SERVICE_NAME || 'local',
      timestamp: new Date().toISOString(),
    });
  } catch {
    res.status(503).json({ status: 'error' });
  }
});

app.listen(process.env.PORT || 3000);

Python / Flask:

# app.py
from flask import Flask, jsonify
import os, datetime

app = Flask(__name__)

@app.route('/health')
def health():
    return jsonify({
        'status': 'ok',
        'service': os.getenv('RENDER_SERVICE_NAME', 'app'),
        'timestamp': datetime.datetime.utcnow().isoformat(),
    })

Python / FastAPI:

# main.py
from fastapi import FastAPI, Response
import os, datetime

app = FastAPI()

@app.get("/health")
def health(response: Response):
    # check dependencies; set response.status_code = 503 on failure
    return {
        "status": "ok",
        "service": os.getenv("RENDER_SERVICE_NAME", "app"),
        "timestamp": datetime.datetime.utcnow().isoformat(),
    }

Render injects PORT and RENDER_SERVICE_NAME automatically. Always bind to PORT.


Step 2: Enable Render's native health check

Render supports health check paths that control deploy promotion. In your service settings:

  1. Go to Settings → Health & Alerts
  2. Set Health Check Path to /health
  3. Set the failure threshold (e.g., 3 consecutive failures)

This prevents a broken deploy from going live. It doesn't give you external alerts — that's what Vigilmon handles.


Step 3: Set up Vigilmon monitoring

With your app deployed on Render, connect it to Vigilmon:

  1. Sign up at vigilmon.online — free, no card required
  2. Click New Monitor → HTTP
  3. URL: https://your-service.onrender.com/health
  4. Check interval: 1 minute (paid) or 5 minutes (free)
  5. Expected status: 200
  6. Save

If you've connected a custom domain, monitor that instead — it covers both your DNS and your Render service:

https://api.yourdomain.com/health

Step 4: Tune for cold starts

Render's free and starter web services spin down after 15 minutes of inactivity. The first request after a spin-down triggers a cold start that can take 10–30 seconds.

To avoid false alerts from cold starts:

  1. In Vigilmon's monitor settings, set Timeout to 30 seconds
  2. Set Confirm Down After to 2 consecutive failures

With these settings, Vigilmon waits for two consecutive failures before alerting. A single cold start shows up as a slow response, not a false-positive outage.

If you're on a Render paid plan with always-on instances, you can lower the timeout to 10 seconds for faster real outage detection.


Step 5: Configure alerts

In Vigilmon, go to Notifications → New Channel:

Slack:

1. Create an incoming webhook at api.slack.com/apps
2. Paste the URL into Vigilmon → Notifications → Slack
3. Enable it on your Render monitors

Email:

1. Add your address as a notification channel
2. Enable on monitors

What you see when a real outage happens:

🔴 DOWN: your-service.onrender.com/health
Status: 0 (connection timeout)
Region: EU-West
5 minutes ago

And on recovery:

✅ RECOVERED: your-service.onrender.com/health
Downtime: 12 minutes

The key difference from a cold start: a real outage produces multiple consecutive failures across different Vigilmon regions. A cold start produces a slow (but successful) response from one region.


Step 6: Monitor Render cron jobs

Render supports cron jobs as a separate service type. A cron job that silently crashes or stops running won't surface in your HTTP monitor — the web service stays green while background work stops.

Add a heartbeat ping to your cron job:

Node.js:

// cron/main.js
import fetch from 'node-fetch';

async function main() {
  try {
    await runScheduledWork();

    const heartbeatUrl = process.env.VIGILMON_CRON_HEARTBEAT;
    if (heartbeatUrl) {
      await fetch(heartbeatUrl);
    }
  } catch (err) {
    console.error('Cron job failed:', err);
    process.exit(1);
  }
}

async function runScheduledWork() {
  // your job logic
}

main();

Python:

# cron/main.py
import os, requests

def main():
    try:
        run_scheduled_work()

        heartbeat_url = os.getenv('VIGILMON_CRON_HEARTBEAT')
        if heartbeat_url:
            requests.get(heartbeat_url, timeout=5)
    except Exception as e:
        print(f'Cron job failed: {e}')
        raise

def run_scheduled_work():
    pass  # your logic

if __name__ == '__main__':
    main()

In Vigilmon:

  1. Click New Monitor → Heartbeat
  2. Set the interval to match your cron schedule
  3. Copy the ping URL
  4. Add VIGILMON_CRON_HEARTBEAT=<url> as a Render environment variable

Step 7: Watch for spin-down patterns in Render

Render free services spin down on idle. If your health check interval is 5 minutes (free Vigilmon tier), the service may spin down between checks and Vigilmon's probe will wake it up each time — masking the spin-down behavior.

To understand your app's idle behavior:

  1. Add Vigilmon's Response Time chart to your dashboard
  2. Look for latency spikes on a regular pattern — those are cold starts
  3. Upgrade Render (to always-on) or Vigilmon (1-minute interval) if the pattern concerns you

The charts give you evidence for the upgrade conversation.


Step 8: Public status page

Go to Status Pages → New Status Page in Vigilmon, add your monitors, and share the URL:

Something broken? Check https://status.yourdomain.com

Each monitor generates a live status badge:

![Service Status](https://vigilmon.online/badge/your-monitor-slug)

What you've built

| What | How | |------|-----| | Health endpoint | Framework-native /health route | | Render deploy protection | Render health check path | | External uptime monitoring | Vigilmon HTTP monitor | | Cold-start tolerance | 30s timeout + 2-failure confirm threshold | | Slack/email alerts | Vigilmon notification channels | | Cron job monitoring | Heartbeat ping in cron service | | Spin-down visibility | Vigilmon response time charts | | Status page | Vigilmon public status page |

Render takes care of deployment. Vigilmon takes care of watching it from the outside.


Next steps

  • Add separate Vigilmon monitors for staging and production Render services
  • Set up response time alerts — Render cold starts that regularly take >10 seconds are a signal to upgrade to always-on
  • Add heartbeats for every Render cron service that does work you'd notice missing

Get started free at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →