QueuePulse

Know the moment your Solid Queue jobs break โ€” without running Datadog.

Solid Queue is the default Active Job backend in Rails 8. Its dashboard, Mission Control Jobs, is great for looking at jobs โ€” but it has no alerting and no historical metrics. So today you either find out your jobs are failing when a customer emails you, or you bolt on a heavyweight APM (Datadog/New Relic) that's overkill for a small app.

QueuePulse fills that gap. It reads Solid Queue's existing tables (read-only, no migration, no extra service) and pings you the moment something goes wrong:

  • ๐Ÿ”ด Job failures โ€” alerted the instant a job lands in failed_executions
  • ๐ŸŸ  Queue latency โ€” oldest job has been waiting too long (work is backing up)
  • ๐ŸŸ  Queue depth โ€” a queue is piling up beyond your threshold
  • ๐ŸŸ  Stuck jobs โ€” a job has been running far longer than it should
  • ๐Ÿ”ด Dead workers โ€” no worker/dispatcher heartbeat = nothing is processing jobs

Delivered to Slack, email, or any webhook.

Status: early. The free gem (this repo) is the open-source core. A hosted dashboard with historical metrics and AI failure summaries is on the roadmap โ€” join the waitlist ยป.

Install

# Gemfile
gem "queue_pulse"
bundle install

Configure

# config/initializers/queue_pulse.rb
QueuePulse.configure do |config|
  config.add_notifier QueuePulse::Notifiers::Slack.new(webhook_url: ENV["SLACK_WEBHOOK_URL"])

  # Optional โ€” every setting has a sensible default:
  config.queue_latency_threshold = 300   # seconds a job may wait before alerting
  config.queue_depth_threshold   = 1_000 # ready jobs per queue before alerting
  config.stuck_job_threshold     = 600   # seconds a running job may take before alerting
  config.alert_cooldown          = 900   # seconds before re-alerting the same condition
  config.environment_label       = Rails.env
end

Run the checks

Schedule it with Solid Queue's own recurring tasks (recommended):

# config/recurring.yml
queue_pulse_check:
  class: QueuePulse::CheckJob
  schedule: every minute

Or run on demand:

bin/rails queue_pulse:check

Or run an in-process poller (opt-in):

QueuePulse.start_poller!  # checks every config.poll_interval seconds

Notifiers

QueuePulse::Notifiers::Slack.new(webhook_url: "https://hooks.slack.com/...")
QueuePulse::Notifiers::Webhook.new(url: "https://example.com/hook", headers: { "Authorization" => "Bearer ..." })
QueuePulse::Notifiers::Email.new(to: "ops@example.com")

Add your own by subclassing QueuePulse::Notifiers::Base and implementing #deliver(alerts).

Design principles

  • No migration, no extra service. Reads Solid Queue tables directly; dedupe state lives in Rails.cache.
  • Safe by default. Read-only queries, every check and notifier is exception-isolated โ€” QueuePulse can never take down your app. Raw job arguments are never sent unless you opt in.
  • Quiet. Cooldowns and burst-collapsing mean you get signal, not spam.

Requirements

Ruby โ‰ฅ 3.1, Rails โ‰ฅ 7.1, solid_queue โ‰ฅ 1.0.

Development

bundle install
rake test

License

MIT โ€” see LICENSE.txt.