tutorial

How to Monitor Your Ruby on Rails App with Uptime Checks and Sidekiq Heartbeats (free)

Stop flying blind. Add HTTP monitoring, Sidekiq heartbeat checks, and Slack alerts to your Rails app in under 30 minutes — for free.

How to Monitor Your Ruby on Rails App with Uptime Checks and Sidekiq Heartbeats (free)

Your Rails app just went down at 3 AM and you found out when a customer emailed you the next morning. Sound familiar?

Most Rails tutorials cover deployment — but almost none cover what to do after you deploy. By the end of this article you'll have HTTP uptime monitoring, Sidekiq heartbeat checks, Slack alerts, and a public status page — all in under 30 minutes, free.


The two failure modes Rails developers miss

Rails production failures cluster into two patterns that are easy to detect but go unnoticed without the right tooling:

Endpoint outages — your /api/health or root URL starts returning 500s or timing out. Users see a broken page, but you don't know until they complain (or worse, they don't complain and just leave).

Silent background job failures — your Sidekiq jobs stop running. The database stops being updated, emails stop going out, Stripe webhooks stop being processed. No exception is raised. Nothing shows up in your logs. You just quietly stop getting results until something downstream explodes.

Both are fixable with a few lines of code and a free monitoring account.


Step 1: Add a health check endpoint

Add the health_check gem to your Gemfile:

# Gemfile
gem 'health_check'

Run:

bundle install

Mount the engine in your routes:

# config/routes.rb
Rails.application.routes.draw do
  mount HealthCheck::Engine, at: '/health'
  # ... your other routes
end

Configure what to check:

# config/initializers/health_check.rb
HealthCheck.setup do |config|
  config.standard_checks = ['database', 'cache', 'migrations']
  config.full_checks = ['database', 'cache', 'migrations', 'email']
end

Now GET /health returns healthy with a 200 when everything is fine and a 500 with details when something is wrong. This single endpoint gives you immediate visibility into your database connection, cache, and migration state.

You can test it locally:

curl http://localhost:3000/health
# healthy

Step 2: Set up HTTP uptime monitoring

With your health endpoint live, point Vigilmon at it:

  1. Sign up for a free account at vigilmon.online
  2. Click New Monitor → HTTP
  3. Enter https://yourdomain.com/health
  4. Set check interval to 5 minutes (free tier)
  5. Save

Vigilmon will now ping your endpoint every 5 minutes from multiple locations. If it goes down, you get alerted before your users notice.

You can also monitor your critical API routes directly:

  • https://yourdomain.com/api/v1/ping — confirms the API layer is responding
  • https://yourdomain.com/ — confirms the frontend is serving

Step 3: Heartbeat monitoring for Sidekiq jobs

HTTP monitoring catches server outages. But what about Sidekiq workers that stop running silently?

The heartbeat pattern: your job pings a URL at the end of every successful run. If Vigilmon stops receiving that ping within the expected interval, it knows the job has stopped or failed.

Here's a Sidekiq worker with a heartbeat ping:

# app/workers/daily_report_worker.rb
class DailyReportWorker
  include Sidekiq::Worker

  sidekiq_options queue: :default, retry: 3

  def perform
    # Your actual job logic
    generate_daily_report

    # Ping the heartbeat URL on success
    heartbeat_url = ENV['DAILY_REPORT_HEARTBEAT_URL']
    if heartbeat_url.present?
      Net::HTTP.get(URI(heartbeat_url))
    end
  rescue => e
    # Don't ping on failure — the absence of a ping IS the alert
    Rails.logger.error("DailyReportWorker failed: #{e.message}")
    raise
  end

  private

  def generate_daily_report
    # your logic here
  end
end

For jobs that run on a schedule (via sidekiq-cron or whenever), set the heartbeat URL in your environment:

# .env or your deployment environment
DAILY_REPORT_HEARTBEAT_URL=https://vigilmon.online/heartbeats/your-unique-token

In Vigilmon, create a Heartbeat Monitor:

  1. Click New Monitor → Heartbeat
  2. Set the expected interval (e.g. every 24 hours)
  3. Copy the unique ping URL
  4. Paste it into your environment as DAILY_REPORT_HEARTBEAT_URL

Now if your worker fails midway, raises an unhandled exception, or simply stops being enqueued — Vigilmon will alert you within one missed interval.

Works with Sidekiq cron schedules

If you're using sidekiq-cron:

# config/schedule.yml
daily_report:
  cron: "0 9 * * *"
  class: "DailyReportWorker"
  queue: default

The heartbeat approach monitors the actual execution, not just whether the job was enqueued. A cron schedule that runs but immediately errors will still miss its ping, triggering an alert.


Step 4: Webhook alerts to Slack or email

Configure alert delivery in Vigilmon:

For Slack:

  1. Create an incoming webhook in your Slack workspace
  2. In Vigilmon, go to Notifications → New Channel → Slack
  3. Paste your webhook URL
  4. Enable it on each monitor you want it to cover

For email:

  1. In Vigilmon, go to Notifications → New Channel → Email
  2. Enter the address (or distribution list)
  3. Enable it on your monitors

You'll get alerts like:

🔴 DOWN: yourdomain.com/health
Status: 500 Internal Server Error
From: US-East, EU-West
Started: 3 minutes ago

And recovery notifications:

✅ RECOVERED: yourdomain.com/health is back UP
Downtime: 11 minutes

For the heartbeat monitor:

🔴 MISSED: DailyReportWorker heartbeat
Expected every: 24 hours
Last ping: 26 hours ago

Step 5: Public status page

A public status page lets your users self-serve the "is it just me?" question. It also builds trust — transparency during incidents keeps customers from churning.

In Vigilmon:

  1. Go to Status Pages → New Status Page
  2. Name it (e.g. "Acme Status")
  3. Select the monitors to display
  4. Save and copy the public URL

You can link to it from your site footer, your README, or your error pages. During an incident, users who hit the status page know the team is aware — they don't need to open a support ticket.


What you've built

| What | How | |------|-----| | HTTP uptime monitoring | health_check gem + Vigilmon HTTP monitor | | Database / cache health | health_check standard checks | | Sidekiq job monitoring | Heartbeat ping at end of each worker | | Instant alerts | Slack or email webhook notifications | | Public status page | Vigilmon status page |

The full setup costs $0 on Vigilmon's free tier and takes less time than tracking down a silent failure that's been running for two days.


Next steps

  • Add a heartbeat for each critical Sidekiq worker, not just the daily ones — treat them like uptime monitors
  • Monitor response time trends: a gradual slowdown before a crash is often detectable hours in advance
  • Add lograge for structured Rails logs that pair well with monitoring dashboards

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 →