Dev.to WebDev 🛠 Dev 👁 0 📖 4 min read

How to Monitor Your Heroku App with Vigilmon (Free External Uptime Monitoring)

Heroku provides basic metrics and logs, but it doesn't give you external uptime monitoring. If your dyno crashes, sleeps (on the free tier), or starts returning 500s, Heroku's internal dashboards won't alert you — your u

Heroku provides basic metrics and logs, but it doesn't give you external uptime monitoring. If your dyno crashes, sleeps (on the free tier), or starts returning 500s, Heroku's internal dashboards won't alert you — your users will.

This guide shows you how to set up external uptime monitoring for your Heroku application using Vigilmon, so you know about downtime before your users do.

What Heroku Monitoring Doesn't Cover

Heroku provides:

  • Application metrics — memory usage, response times, throughput
  • Log drains — pipe logs to a third-party service (Papertrail, Logtail)
  • Dyno restart notifications — in the activity feed

What Heroku doesn't provide:

  • External uptime checks — validation from outside Heroku's network
  • Instant downtime alerts — the activity feed is not real-time alerting
  • SSL certificate expiry warnings — you need to track this yourself
  • Multi-region validation — if Heroku's US region has issues, you want an independent observer

Step 1: Add a Health Check Endpoint to Your App

Before setting up monitoring, ensure your app has a health check route that returns a clear success signal.

Node.js (Express):

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

Python (Flask):

@app.route('/health')
def health():
    return {'status': 'ok', 'timestamp': datetime.utcnow().isoformat()}, 200

Ruby on Rails:

# config/routes.rb
get '/health', to: proc { [200, {}, ['{"status":"ok"}']] }

Python (Django):

# urls.py
from django.http import JsonResponse

def health(request):
    return JsonResponse({'status': 'ok'})

urlpatterns = [
    path('health', health),
    # ... your other routes
]

Deploy your changes:

git add .
git commit -m "Add health check endpoint"
git push heroku main

Step 2: Prevent Dyno Sleep (If on a Free or Eco Plan)

Heroku's Eco dynos sleep after 30 minutes of inactivity. Vigilmon's regular health checks will keep your dyno awake as a side effect — but this is actually the desired behavior: you want your app available 24/7.

If you're using Heroku's Basic or Standard dynos, sleeping isn't an issue.

Step 3: Set Up Vigilmon to Monitor Your Heroku App

  1. Go to vigilmon.online and sign up (free tier, no credit card)
  2. Click Add Monitor
  3. Enter your app's health URL:
   https://your-app-name.herokuapp.com/health

Or your custom domain if you've configured one:

   https://app.yourdomain.com/health
  1. Set check interval: every 1 minute
  2. Set expected status code: 200
  3. Optionally add a keyword check: "status":"ok"
  4. Add your alert channels:
    • Email (enter your address)
    • Slack (paste your webhook URL)
    • Webhook (for PagerDuty or custom integrations)
  5. Click Save

Vigilmon will now check your Heroku app from multiple regions every minute. If any check fails, you'll get an alert immediately.

Step 4: Monitor SSL Certificate Expiry

If your Heroku app uses a custom domain with ACM (Automated Certificate Management), the cert is auto-renewed — but it's worth monitoring as a safety net.

In Vigilmon, when you add your custom domain URL, SSL monitoring is included automatically. You'll receive an alert if your cert is approaching expiry.

Step 5: Make Your Health Check More Thorough (Optional)

For production apps that depend on external services, expand your health check to validate those dependencies:

Node.js with database check:

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

app.get('/health', async (req, res) => {
  const checks = {};
  let allOk = true;

  try {
    await pool.query('SELECT 1');
    checks.database = 'ok';
  } catch (e) {
    checks.database = 'error';
    allOk = false;
  }

  res.status(allOk ? 200 : 503).json({
    status: allOk ? 'ok' : 'degraded',
    checks
  });
});

Python with Redis check:

import redis

@app.route('/health')
def health():
    checks = {}
    all_ok = True

    try:
        r = redis.from_url(os.environ.get('REDIS_URL'))
        r.ping()
        checks['redis'] = 'ok'
    except Exception:
        checks['redis'] = 'error'
        all_ok = False

    status = 'ok' if all_ok else 'degraded'
    code = 200 if all_ok else 503
    return jsonify({'status': status, 'checks': checks}), code

What a Heroku Monitoring Setup Should Cover

Monitor What It Catches Setup
HTTP uptime on /health Dyno crashes, app errors 2 min
Keyword check ("status":"ok") Silent failures, degraded state Add to same monitor
SSL cert expiry Cert renewal failures Auto in Vigilmon
Custom domain check DNS misconfiguration Add second monitor

Common Heroku Monitoring Scenarios

Web dyno crashes: Vigilmon will detect the 503/timeout within 60 seconds and alert you via Slack or email.

Database connection pool exhaustion: If your health check validates DB connectivity, you'll see it return 503 before all your users start hitting errors.

Memory quota exceeded: Heroku R14 errors cause slow responses — Vigilmon's response time tracking will show degradation before the dyno is killed.

Setting Up Alerts

For production Heroku apps, configure at minimum:

  • Email alert — immediate notification when the check fails
  • Slack webhook — team visibility for faster incident response

For critical apps, add:

  • Webhook to PagerDuty — escalation for on-call teams
  • Status page — public-facing Vigilmon status page so your users can self-serve status updates during incidents

Summary

Heroku monitoring with Vigilmon takes about 5 minutes to set up:

  1. Add a /health endpoint to your app
  2. Push to Heroku
  3. Add the URL to Vigilmon
  4. Configure your alert channel

You'll have external uptime monitoring from multiple regions, catching downtime before your users do.

Try Vigilmon free: vigilmon.online

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.