DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your Sidekiq Workers with Vigilmon

How to Monitor Your Sidekiq Workers with Vigilmon

Sidekiq is the most popular background job processor for Ruby on Rails applications — used for sending emails, processing webhooks, generating reports, and handling anything that shouldn't block a request. When Sidekiq goes down, it goes down quietly: no 500 errors, no user-facing failures — just a growing job backlog and eventually, users wondering why nothing is happening.

This guide shows how to monitor Sidekiq with Vigilmon — from worker health to queue depth and scheduled job verification.


How Sidekiq Fails

  • Process crash — Sidekiq exits; Rails continues serving requests normally while jobs pile up
  • Redis connection lost — Sidekiq can't connect to Redis; jobs queue locally and eventually drop
  • Dead job explosion — failed jobs that exceed max_retries accumulate in the dead set
  • Cron job drift — Sidekiq-Cron or Sidekiq-Scheduler stops firing scheduled jobs
  • Memory exhaustion — Sidekiq worker OOMs after processing large jobs; the process exits silently

Step 1: Add a Heartbeat Job to Sidekiq

The most reliable Sidekiq health check is a scheduled job that pings a heartbeat URL:

# app/jobs/health_heartbeat_job.rb
class HealthHeartbeatJob < ApplicationJob
  queue_as :health

  def perform
    heartbeat_url = ENV.fetch('VIGILMON_HEARTBEAT_URL', nil)
    return unless heartbeat_url

    require 'net/http'
    uri = URI(heartbeat_url)
    Net::HTTP.get(uri)
  rescue => e
    Rails.logger.error("Health heartbeat failed: #{e.message}")
  end
end
Enter fullscreen mode Exit fullscreen mode

Schedule it with Sidekiq-Cron:

# config/schedule.yml (sidekiq-cron)
health_heartbeat:
  cron: '* * * * *'  # Every minute
  class: 'HealthHeartbeatJob'
  queue: health
Enter fullscreen mode Exit fullscreen mode

In Vigilmon, create a Heartbeat monitor with:

  • Expected interval: 1 minute
  • Grace period: 90 seconds

If the heartbeat stops, either Sidekiq is down or the scheduler stopped.


Step 2: Expose a Sidekiq Health Endpoint in Rails

Add a Rails route that checks Sidekiq's status:

# config/routes.rb
get '/health/sidekiq', to: 'health#sidekiq'
Enter fullscreen mode Exit fullscreen mode
# app/controllers/health_controller.rb
class HealthController < ApplicationController
  skip_before_action :authenticate_user!, only: [:sidekiq]

  def sidekiq
    # Check Redis connection
    Sidekiq.redis { |conn| conn.ping }

    # Get queue stats
    stats = Sidekiq::Stats.new
    queue_size = Sidekiq::Queue.new.size
    dead_size = Sidekiq::DeadSet.new.size

    if dead_size > 100
      render json: { status: 'degraded', dead_jobs: dead_size }, status: :service_unavailable
    elsif queue_size > 10_000
      render json: { status: 'degraded', queue_depth: queue_size }, status: :service_unavailable
    else
      render json: {
        status: 'ok',
        queue_size: queue_size,
        dead_jobs: dead_size,
        processed: stats.processed,
        failed: stats.failed
      }, status: :ok
    end
  rescue Redis::CannotConnectError => e
    render json: { status: 'error', error: e.message }, status: :service_unavailable
  end
end
Enter fullscreen mode Exit fullscreen mode

Monitor https://your-app.com/health/sidekiq with Vigilmon.


Step 3: Monitor Sidekiq Web UI

Sidekiq ships with a Rack-based web UI for monitoring queue status:

# config/routes.rb
require 'sidekiq/web'
Sidekiq::Web.use(Rack::Auth::Basic) { |u, p| u == 'admin' && p == ENV['SIDEKIQ_WEB_PASSWORD'] }
mount Sidekiq::Web, at: '/sidekiq'
Enter fullscreen mode Exit fullscreen mode

Monitor https://your-app.com/sidekiq/ — it returns 200 when Sidekiq is running and Redis is reachable.


Step 4: Monitor Queue Depth via a Cron Heartbeat

For precise queue depth monitoring, add a system cron:

#!/bin/bash
# sidekiq-queue-check.sh
cd /app

DEPTH=$(bundle exec rails runner \
  "puts Sidekiq::Queue.new.size" 2>/dev/null)

MAX_DEPTH=${MAX_QUEUE_DEPTH:-5000}

if [ -n "$DEPTH" ] && [ "$DEPTH" -lt "$MAX_DEPTH" ]; then
  curl -sf "$VIGILMON_HEARTBEAT_URL" > /dev/null
fi
Enter fullscreen mode Exit fullscreen mode
*/5 * * * * www-data /usr/local/bin/sidekiq-queue-check.sh
Enter fullscreen mode Exit fullscreen mode

Sidekiq Monitoring Coverage Table

Monitor Type Target Alert Condition
Heartbeat Scheduled health job No ping in > 90 seconds
HTTP(S) /health/sidekiq Rails endpoint Status != 200
HTTP(S) Sidekiq Web UI /sidekiq/ Status != 200
Heartbeat Queue depth cron No ping if queue > 5000

Common Sidekiq Failure Scenarios

Deployment kills workers: During a Rails deploy, Sidekiq processes are restarted. Without a proper warm restart, in-flight jobs may fail. The heartbeat gap during deploy surfaces this.

Redis OOM: Redis evicts keys when memory is full. Sidekiq jobs are lost silently. The heartbeat job enqueue fails — Vigilmon fires an alert.

Dead job explosion: A broken API causes 1000 jobs to fail over an hour. The /health/sidekiq endpoint returns 503 (dead_jobs > 100). Vigilmon alerts within 60 seconds.


Conclusion

Sidekiq is essential infrastructure for Rails apps, but it fails silently. A heartbeat job combined with a health endpoint gives you both the early warning (heartbeat stops) and the diagnosis (endpoint explains why).

Monitor your Sidekiq workers free at vigilmon.online

Top comments (0)