How to monitor scheduled jobs in Rails
How you monitor a scheduled job in Rails depends on how it's scheduled. With Solid Queue (the default Active Job backend in Rails 8), recurring tasks are defined in config/recurring.yml and run by the Solid Queue supervisor, so you monitor the supervisor process and each task. With the whenever gem, your schedule compiles to plain crontab entries, so you monitor it like any cron job. In both cases, the reliable approach is to have the job ping an external monitor on success and alert when the ping is missed.
How are scheduled jobs run in Rails?
There are two common setups, and they fail differently:
- Solid Queue recurring tasks (Rails 8 default): recurring jobs are declared in config/recurring.yml and dispatched by the Solid Queue supervisor process. If that supervisor isn't running, the recurring tasks don't get enqueued — and nothing errors.
- The whenever gem: you write the schedule in config/schedule.rb, and `whenever` generates crontab entries that run rake tasks or runners. This is plain cron under the hood, so it inherits cron's silent-failure behavior.
How do I monitor a Solid Queue recurring task?
Have the job itself report success as its final step. A missed ping then means either the supervisor didn't dispatch it or the job failed:
production:
nightly_report:
class: NightlyReportJob
schedule: every day at 3amrequire "net/http"
class NightlyReportJob < ApplicationJob
PING_URL = "https://ping.cronshield.com/<your-check-id>"
def perform
do_the_work
# Report success last. If perform raises, this line is skipped and the
# monitor alerts on the missed ping.
Net::HTTP.get_response(URI(PING_URL))
end
endHow do I monitor a whenever-scheduled job?
Because whenever produces crontab entries, append the heartbeat in the schedule so it becomes part of the generated cron line, or ping from inside the rake task. Ping only on success:
every :day, at: "3:00 am" do
# The && ensures the ping fires only if the command succeeded.
command "cd :path && :environment_variable=:environment bundle exec rake reports:nightly && curl -fsS -m 10 'https://ping.cronshield.com/<your-check-id>'"
endHow do I know if the whole scheduler stopped?
For Solid Queue, if the supervisor process dies, no recurring task is enqueued and every per-task heartbeat goes silent — which the monitor reads as misses across the board. For whenever, a missing crontab or a stopped cron daemon does the same. Set each monitor's expected period to match its schedule so a stalled scheduler surfaces fast. On paid tiers, CronShield adds the failing job's last log line and a likely cause to the alert.
Add a missed-run alert to this job
The free tier gives you a heartbeat endpoint and an email alert when an expected ping doesn't arrive. Paid tiers add the log-aware diagnosis — the last log line and a likely cause in the alert. The heartbeat receiver ships in an upcoming release; see the plans to learn what each tier adds.
Frequently asked questions
- Does Solid Queue replace the whenever gem for scheduling?
- For recurring jobs, yes — Solid Queue (the Rails 8 default Active Job backend) handles recurring tasks natively through config/recurring.yml, run by its supervisor, with no external cron or whenever gem needed. Teams on older setups or who prefer OS-level cron still use whenever, which generates crontab entries.
- Where do I put the heartbeat in a Rails job?
- Put it as the last line of the job's perform method (or the rake task), after the real work. That way an exception earlier in the method skips the ping, so a failed run withholds its heartbeat and the monitor alerts you.