tutorial

Monitoring Your Railway.app Deployment with Vigilmon

Add external uptime monitoring to apps deployed on Railway — health check routes, Vigilmon ping monitors, and alerts when your Railway service goes down.

Monitoring Your Railway.app Deployment with Vigilmon

Railway makes deployment fast. You push code, Railway builds and runs it. But Railway doesn't tell you when your app goes down from the outside — it only shows you internal metrics and logs. If your deployed service starts returning errors or timing out, you need an external monitor to catch it.

This tutorial covers:

  • A health check route for Node/Python/Go apps on Railway
  • Vigilmon HTTP monitoring for your Railway service URL
  • Alert configuration for downtime and recovery
  • Heartbeat monitoring for Railway cron jobs

Step 1: Add a health check route to your app

Railway auto-generates a public URL for each service. Your monitor will probe this URL, so you need a lightweight route that returns 200 when healthy and something else when not.

Node.js / Express:

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

const app = express();

app.get('/health', (req, res) => {
  res.json({
    status: 'ok',
    service: process.env.RAILWAY_SERVICE_NAME || 'app',
    region: process.env.RAILWAY_REGION || 'unknown',
    timestamp: new Date().toISOString(),
  });
});

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

Python / FastAPI:

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

app = FastAPI()

@app.get("/health")
def health():
    return {
        "status": "ok",
        "service": os.getenv("RAILWAY_SERVICE_NAME", "app"),
        "timestamp": datetime.datetime.utcnow().isoformat(),
    }

Go:

// main.go
package main

import (
    "encoding/json"
    "net/http"
    "os"
    "time"
)

func healthHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(map[string]string{
        "status":    "ok",
        "service":   os.Getenv("RAILWAY_SERVICE_NAME"),
        "timestamp": time.Now().UTC().Format(time.RFC3339),
    })
}

func main() {
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
    http.HandleFunc("/health", healthHandler)
    http.ListenAndServe(":"+port, nil)
}

Railway injects PORT automatically — always bind to it instead of hardcoding.


Step 2: Configure Railway's health check

Railway supports native health checks that control whether traffic is routed to your service. In your Railway service settings:

  1. Go to Settings → Deploy → Health Check Path
  2. Set it to /health
  3. Set Health Check Timeout to 300 seconds

This prevents Railway from routing traffic to a broken deploy. Combined with Vigilmon's external monitoring, you get both internal routing protection and external alerting.


Step 3: Set up Vigilmon monitoring

Once your app is deployed and the Railway URL is live, connect it to Vigilmon:

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

You can also add monitors for your custom domain if you've set one up:

https://api.yourdomain.com/health     → production service
https://staging.yourdomain.com/health → staging service

Monitoring both environments means you catch staging regressions before they hit production.


Step 4: Handle Railway cold starts and spin-downs

Railway's hobby plan services spin down after inactivity. When a request hits a spun-down service, it takes a few seconds to start — Vigilmon may see this as a timeout depending on your threshold.

To avoid false alerts:

  1. In Vigilmon, set Timeout to 15 seconds (instead of the default 5–10)
  2. Set Confirm Down After to 2 consecutive failures before alerting

This gives Railway enough time to spin up on the first probe while still catching real outages quickly.

If you're on a Railway paid plan with always-on services, you can keep the default timeout.


Step 5: Alert configuration

In Vigilmon, go to Notifications → New Channel:

Slack alerts:

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

Email alerts:

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

When your Railway service goes down:

🔴 DOWN: your-service.up.railway.app/health
Status: 503
Region: US-East
2 minutes ago

And when Railway restarts it and it recovers:

✅ RECOVERED: your-service.up.railway.app/health
Downtime: 4 minutes

Step 6: Monitor Railway cron jobs with heartbeats

Railway supports cron jobs as separate services. If a cron job stops running silently — due to a crash, a missed schedule, or a Railway outage — your HTTP monitor won't catch it.

Use a heartbeat: the job pings a Vigilmon URL at the end of every successful run. If Vigilmon doesn't receive a ping within the expected window, it alerts you.

Node.js cron job with heartbeat:

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

async function runJob() {
  try {
    await doWork();

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

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

runJob();

In Vigilmon:

  1. Click New Monitor → Heartbeat
  2. Set the interval to match your Railway cron schedule (e.g., 1 hour)
  3. Copy the ping URL
  4. Add VIGILMON_CRON_HEARTBEAT=<url> as a Railway environment variable

Step 7: Public status page

Go to Status Pages → New Status Page in Vigilmon, add your Railway service monitors, and publish the URL. Drop it in your app's error pages or README:

Service issues? Check our status page: https://status.yourdomain.com

Each monitor also generates a live badge:

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

What you've built

| What | How | |------|-----| | Health endpoint | Framework-native /health route | | Railway deploy protection | Railway health check path | | External uptime monitoring | Vigilmon HTTP monitor | | Cold-start tolerance | Vigilmon timeout + confirm-down settings | | Slack/email alerts | Vigilmon notification channels | | Cron job monitoring | Heartbeat ping in cron handler | | Status page | Vigilmon public status page |

Railway handles deployment. Vigilmon handles visibility. Together they give you a complete picture of whether your service is actually working.


Next steps

  • Add separate monitors for each Railway environment (production, staging, preview)
  • Watch Vigilmon's response time charts — Railway cold starts show up as latency spikes
  • Add heartbeat monitors for every Railway cron service that does important work

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 →