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
- Go to vigilmon.online and sign up (free tier, no credit card)
- Click Add Monitor
- 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
- Set check interval: every 1 minute
- Set expected status code: 200
- Optionally add a keyword check:
"status":"ok" - Add your alert channels:
- Email (enter your address)
- Slack (paste your webhook URL)
- Webhook (for PagerDuty or custom integrations)
- 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:
- Add a
/healthendpoint to your app - Push to Heroku
- Add the URL to Vigilmon
- Configure your alert channel
You'll have external uptime monitoring from multiple regions, catching downtime before your users do.
Try Vigilmon free: vigilmon.online
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.