Cron Jobs

Scheduling Cron Jobs in Ruby

By: August Flanagan|Last Updated: Mar 17, 2023

Ruby is one of the most beloved programming languages of the web era. so it's not surprising that it's used extensively for writing cron jobs.

In this article you’ll learn how to run any Ruby script as a cron job. We'll also explore some popular Ruby libraries that make it easier to manage cron jobs or replace them with tools like Sidekiq that avoid some of the pitfalls of traditional cron jobs.

What is a cron job?

Traditionally, cron jobs are user-defined scripts/commands that are executed on a repeating schedule by the Linux cron scheduler. However the term is now broadly used to mean a piece of code running in the background on a repeatable schedule..

What the * * * * * ?!?

One of the strangest parts of a cron job is the scheduling syntax, e.g.  */3 2 * * 0-3.

Reminiscent of regular expressions, it is very hard to remember. See our guide on cron schedule syntax or use crontab.guru to translate a cron expression to english.

Run a Ruby script as a cron job

This script can be executed from the command prompt as:

ruby /path/to/script.rb

It's useful to manually test any new script before running it as a cronjob. Even if you don't see any errors when running it directly, you will want to take a look at the important considerations listed below to understand some of the ways that cron jobs can silently fail.

Editing the Crontab

From the command line on your server, run crontab -e to access your crontab in a text editor. From there, you can paste or write in your crontab entry to run your Ruby script. To run our cron job a midnight every day we will add the following line:

0 0 * * * ruby /path/to/script.rb

What the * * * * ?!?

The syntax for cron schedules is terse and tricky to remember. Our guide on Linux cron jobs covers cron syntax in detail.

Run cron jobs with the Whenever gem

While it's fairly easy to set up a simple example cron job, managing cron jobs can be tedious and error-prone. Writing and testing cron syntax can be difficult, especially for developers who are not familiar with the nuances of the Unix cron system. And trying to manage a large number of jobs without proper environments and version control can quickly turn to madness.

The whenever gem simplifies this process by allowing developers to define their cron jobs in Ruby code. Instead of writing complex cron syntax, developers can use a simple, readable DSL to define their jobs. Whenever then generates a proper crontab file and installs it on your server(s).

# execute a command
every 5.minutes do
   command "/usr/bin/my_command"
end

Whenever also makes it easy to manage cron jobs across multiple servers using the concept of roles. Developers can define sets of jobs for different sets of servers by assigning those servers "roles" (e.g. app or db), and Whenever will generate separate cron files for each of those servers based on the assigned roles.

every :day, at: '1:37pm', roles: [:app] do
  rake 'app:task' # will only be added to crontabs of :app servers
end

every :hour, roles: [:db] do
  rake 'db:task' # will only be added to crontabs of :db servers
end

every :day, at: '12:02am' do
  command "run_this_everywhere" # will be deployed to :db and :app servers
end

Run cron jobs with Sidekiq

Sidekiq is a popular library for running Ruby code in the background (asynchronously). Sidekiq enterprise, and the open-source sidekiq-scheduler gem both provide ways to run cron jobs via Sidekiq instead of relying on crontab.

This has some big advantages over traditional cron jobs. The queue-based architecture of Sidekiq means that important jobs can be priorized, failed jobs retried and long-running/intensive jobs are (often) easier to scale horizontally.

Sidekiq Enterprise

# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  # register any Jobs to be run on a cron based schedule
  config.periodic do |mgr|
    mgr.register "* * * * *", EveryMinuteJob, retry: 1
    mgr.register "*/4 * 10 * *", OddlyTimedCriticalJob, queue: 'critical'
  end
end

Monitor Ruby cron jobs

No matter which tool you use, it's important to consider how you will monitor your cron jobs — it's too easy for them to fail silently. That's where a tool like Cronitor comes in. Cronitor makes it easy to monitor your cron jobs, and will alert you immediately when a job fails, or doesn't run on time.

Cronitor has SDKs for both Ruby and Sidekiq that make it easy to add monitoring with just a couple of lines of code.

Monitoring Ruby Cron Jobs

# Sample Ruby configuration
require 'cronitor'
# everything within the block is monitored,
# and errors are reported automatically
Cronitor.job 'important-job' do
    ImportantJob.new(Date.today).run()
end

Monitoring Sidekiq Cron Jobs

# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.server_middleware do |chain|
    chain.add Sidekiq::Cronitor::ServerMiddleware
  end
end

# sync any cron job schedules to Cronitor
Sidekiq::Cronitor::PeriodicJobs.sync_schedule!

If you are using Sidekiq, be sure to check out our complete guide to Sidekiq Monitoring

Previous
Node.js Cron Jobs