Sidekiq is the standard background job processor for Ruby on Rails applications. Transactional emails, payment processing, image resizing, CSV exports, and scheduled reminders all run through it. When Sidekiq goes down — because the Redis connection drops, the process crashes, or the dyno restarts — jobs queue up silently. Your Rails app continues to accept requests and return 200 responses, but nothing actually happens behind the scenes. Users wait for emails that never arrive. Payments that appeared to succeed never settled. The issue only surfaces when a user or customer escalates.
This tutorial covers production-grade uptime monitoring for Sidekiq using Vigilmon. We will walk through:
- Exposing a Sidekiq health check endpoint in your Rails application
- Monitoring the Sidekiq Web UI
- SSL certificate monitoring for your job processing endpoints
- Webhook alerts for DOWN/UP events
Prerequisites
- Ruby on Rails application with Sidekiq configured
- Redis as the Sidekiq job broker
- A free account at vigilmon.online
Part 1: Add a Sidekiq health check endpoint
Rails does not include a Sidekiq health check out of the box. Add one that verifies Sidekiq can reach Redis and that at least one worker process is running.
Add the health check route
# config/routes.rb
Rails.application.routes.draw do
get "/health/sidekiq", to: "health#sidekiq"
# ... your other routes
end
Implement the controller
# app/controllers/health_controller.rb
class HealthController < ApplicationController
skip_before_action :authenticate_user!, only: [:sidekiq]
def sidekiq
# Verify Redis connectivity
Sidekiq.redis { |conn| conn.ping }
# Check for live workers
workers = Sidekiq::Workers.new.count
processes = Sidekiq::ProcessSet.new.count
if processes.zero?
render json: { status: "error", detail: "No Sidekiq processes registered" },
status: :service_unavailable
return
end
render json: {
status: "ok",
processes: processes,
workers: workers,
}, status: :ok
rescue Redis::CannotConnectError, Redis::TimeoutError => e
render json: { status: "error", detail: e.message },
status: :service_unavailable
end
end
Verify the endpoint
# Start Sidekiq
bundle exec sidekiq &
# Test the endpoint
curl -s http://localhost:3000/health/sidekiq | python3 -m json.tool
Expected response with Sidekiq running:
{
"status": "ok",
"processes": 1,
"workers": 0
}
Response when Redis is unreachable or no Sidekiq processes are registered:
{
"status": "error",
"detail": "No Sidekiq processes registered"
}
Part 2: Expose the health endpoint for external monitoring
Your Rails application typically runs behind nginx or Caddy with TLS. Make the health endpoint accessible to Vigilmon's external check nodes.
nginx configuration
# /etc/nginx/sites-available/myapp
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
# Health endpoint — bypass authentication middleware
location = /health/sidekiq {
proxy_pass http://127.0.0.1:3000/health/sidekiq;
proxy_set_header Host $host;
proxy_read_timeout 10s;
access_log off;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Caddy configuration
app.example.com {
handle /health/sidekiq {
reverse_proxy localhost:3000
}
handle {
reverse_proxy localhost:3000
}
}
Verify external accessibility:
curl https://app.example.com/health/sidekiq
# {"status":"ok","processes":1,"workers":0}
Part 3: Set up HTTP monitoring in Vigilmon
Monitor Sidekiq worker processes
- Log in to vigilmon.online and click Add Monitor.
- Choose HTTP(S) monitor.
- Enter:
https://app.example.com/health/sidekiq - Set interval to 1 minute.
- Add a keyword check: must contain
"status":"ok". - Add your alert channel.
- Click Save.
Monitor the Sidekiq Web UI
If you mount the Sidekiq Web UI (as recommended for visibility into queue depth and job history), add a separate monitor for it:
- Add Monitor → HTTP(S)
- URL:
https://app.example.com/sidekiq(or your mount path) - Set expected HTTP status to 200 or 302 (redirect to login).
- Interval: 1 minute
| Component | Monitor URL | Keyword |
|-----------|-------------|---------|
| Worker health | https://app.example.com/health/sidekiq | "status":"ok" |
| Sidekiq Web UI | https://app.example.com/sidekiq | — (status 200/302) |
| Redis connectivity | https://app.example.com/health/redis | ok |
Part 4: Monitor Redis separately
Redis is Sidekiq's message broker and job store. If Redis goes down, Sidekiq workers drain their in-memory queue and then idle — no new jobs are picked up, but workers appear healthy.
# app/controllers/health_controller.rb (add to existing controller)
def redis
Sidekiq.redis { |conn| conn.ping }
render json: { status: "ok" }, status: :ok
rescue Redis::CannotConnectError, Redis::TimeoutError => e
render json: { status: "error", detail: e.message }, status: :service_unavailable
end
# config/routes.rb
get "/health/redis", to: "health#redis"
Add a Vigilmon monitor:
- Add Monitor → HTTP(S)
- URL:
https://app.example.com/health/redis - Keyword:
"status":"ok" - Interval: 1 minute
Keeping Redis and Sidekiq as separate monitors immediately tells you whether "jobs not processing" is caused by a dead worker or a dead broker — two different runbooks.
Part 5: SSL certificate monitoring
Sidekiq workers running in separate processes connect to Redis over TLS in most production setups. An expired certificate on your Redis host causes a complete worker outage — Sidekiq cannot reconnect after the initial TLS handshake fails.
- In Vigilmon, click Add Monitor.
- Choose SSL monitor.
- Enter:
app.example.com - Set alert threshold to 14 days before expiry.
- Add your alert channel.
- Click Save.
If Redis uses TLS on a separate host (e.g., redis.example.com), add a separate SSL monitor for it.
Part 6: Webhook alerts for DOWN events
Integrate Vigilmon alerts with your incident management system:
// webhook-receiver.ts
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhook/vigilmon', (req, res) => {
const { monitor_name, status, url, response_code, checked_at } = req.body;
if (status === 'down') {
console.error('[VIGILMON] Sidekiq monitor DOWN', {
monitor: monitor_name,
url,
code: response_code,
at: checked_at,
});
postSlackAlert({
text: `⚠️ Sidekiq is DOWN\n${url}\nHTTP ${response_code}\nBackground jobs are not processing.`,
channel: '#rails-alerts',
});
createPagerDutyIncident({
title: `Sidekiq unavailable — ${monitor_name}`,
severity: 'high',
details: { url, response_code, checked_at },
});
} else if (status === 'up') {
console.info('[VIGILMON] Sidekiq recovered', { monitor: monitor_name });
postSlackAlert({
text: `✅ Sidekiq recovered\n${url}`,
channel: '#rails-alerts',
});
}
res.sendStatus(204);
});
app.listen(3000);
Vigilmon sends this payload on DOWN and UP transitions:
{
"monitor_id": "mon_abc123",
"monitor_name": "Sidekiq Worker Health",
"status": "down",
"url": "https://app.example.com/health/sidekiq",
"checked_at": "2026-06-30T09:00:00Z",
"response_code": 503,
"response_time_ms": 2810
}
Part 7: Kubernetes deployments
For Sidekiq deployed as a Kubernetes Deployment alongside your Rails web pods:
# sidekiq-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sidekiq
namespace: myapp
spec:
replicas: 2
selector:
matchLabels:
app: sidekiq
template:
metadata:
labels:
app: sidekiq
spec:
containers:
- name: sidekiq
image: myapp:latest
command: ["bundle", "exec", "sidekiq"]
args: ["-C", "config/sidekiq.yml"]
livenessProbe:
exec:
command:
- bundle
- exec
- sidekiqmon
- processes
initialDelaySeconds: 30
periodSeconds: 60
timeoutSeconds: 15
failureThreshold: 3
env:
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: redis-url
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: database-url
For Vigilmon to reach the health endpoint, it must be served by your Rails web pods, not the Sidekiq pods. Ensure the Ingress routes /health/sidekiq to the web deployment:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
namespace: myapp
spec:
tls:
- hosts:
- app.example.com
secretName: myapp-tls
rules:
- host: app.example.com
http:
paths:
- path: /health
pathType: Prefix
backend:
service:
name: myapp-web
port:
number: 3000
Summary
Your Sidekiq deployment now has four layers of monitoring:
- Worker process check — queries Sidekiq's process registry and verifies at least one worker is alive, polled every 60 seconds by Vigilmon.
- Redis broker monitor — a separate check so you can distinguish between a crashed Sidekiq process and a lost Redis connection.
- SSL monitor — alerts you 14 days before certificate expiry, before TLS handshakes start failing.
- Webhook/PagerDuty alerts — DOWN events with severity tagging reach your on-call rotation within one check interval.
Vigilmon handles check scheduling, multi-region polling, alert routing, and uptime history. When Sidekiq goes down, your team knows within 60 seconds — before a customer notices their order confirmation email never arrived.
Monitor your Sidekiq infrastructure free at vigilmon.online
#sidekiq #ruby #rails #backgroundjobs #monitoring #uptime