Skip to main content

rufus-scheduler - Ruby cron & interval scheduling

At 04:30, every day.

Next runs · UTC

Calendar

September 2026 · UTC

0 runs

About this tool

rufus-scheduler is the most popular pure-Ruby scheduler. It accepts cron syntax (via Fugit), interval shorthand (every '5m'), one-shot scheduling (at, in), and IANA timezones. It runs in-process, so the schedule lives as long as the Ruby process.
For durable scheduling across restarts and a worker fleet, pair rufus-scheduler with sidekiq-cron or use a system cron tied to a dedicated worker.

Basic rufus-scheduler usage

ruby
require 'rufus-scheduler'


scheduler = Rufus::Scheduler.new


# Cron
scheduler.cron '0 9 * * 1-5', tz: 'America/New_York' do
  Reports.send_morning_digest
end


# Interval
scheduler.every '5m' do
  Heartbeat.ping
end


# One-shot
scheduler.in '30s' do
  Cleanup.run
end


scheduler.join

Cron syntax in rufus

  • Standard 5-field: 0 9 * * 1-5
  • 6-field with seconds at the front: 30 0 9 * * 1-5
  • Descriptors: '@hourly', '@daily', '@weekly', '@monthly', '@yearly'
  • Last day: 0 0 L * * (Fugit supports L)
  • Aliases: 0 9 * * MON-FRI

Timezones in rufus

ruby
# Daily 09:00 in New York, regardless of DST
scheduler.cron '0 9 * * *', tz: 'America/New_York' do
  daily_job
end


# Daily 09:00 UTC
scheduler.cron '0 9 * * *', tz: 'UTC' do
  daily_utc_job
end


# Without tz: uses the host system's timezone
scheduler.cron '0 9 * * *' do
  ambiguous_job
end

Always pass tz: in production. The host timezone may differ across deployments and changes silently with the OS configuration.

rufus-scheduler pitfalls

  • In-process only - the schedule dies with the Ruby process. For durability, use sidekiq-cron or a system cron.
  • Multi-process Rails - every Puma worker runs the scheduler unless you gate on Process.pid or use a leader-election lib. Otherwise the cron fires N times per tick.
  • Long-running blocks - by default jobs run in their own thread, so a slow job doesn't block others. But many slow jobs at once can exhaust the thread pool.
  • Overlap - pass overlap: false to skip a tick if the previous run is still going.

Examples

  • 0 18 * * *
    Every day at 18:00
  • 0 */5 * * *
    Every 5 hours
  • 0 18 * * 1-5
    Weekdays at 18:00
  • 0 0 1 * *
    Once a month, on the 1st at midnight

Cheatsheet

Full cheatsheet
FieldReq.RangeWildcards
minuteyes0-59, - * /
houryes0-23, - * /
day of monthyes1-31, - * /
monthyes1-12 or JAN-DEC, - * /
day of weekyes0-6 or names; some dialects use 0-7 or 1-7 — see Dialects, - * /

Frequently asked questions

Syntax

What cron syntax does rufus-scheduler support?

rufus-scheduler accepts standard 5-field and 6-field (with seconds) cron syntax via its Fugit parser. It also supports every '5m'-style interval syntax, at syntax for one-shot jobs, and in '10s' for delayed jobs.

Does rufus-scheduler support L, W, # modifiers?

Partially. Fugit, rufus-scheduler's parser, supports L for last-day rules and # for nth-weekday rules, but it does not support W.

Can rufus-scheduler use both five- and six-field cron?

Yes. rufus-scheduler accepts standard five-field cron and a six-field form with seconds first. Keep five fields when portability to Unix crontab matters.

Which cron aliases does Fugit document for rufus-scheduler?

Fugit documents @yearly, @monthly, @weekly, @daily, @midnight, and @hourly. Each expands to its corresponding five-field calendar schedule.

Timing

When should I use every '10m' instead of cron in rufus?

Use every '10m' for an elapsed-time interval and cron for wall-clock alignment. A cron such as */10 * * * * targets minute 0, 10, 20, and so on. Expression: */10 * * * *

Open in editor

Days and months

Can rufus-scheduler run on the last day of each month?

Yes. Fugit documents 0 0 L * * and 0 0 last * * for midnight on the last calendar day of each month.

Can Fugit select the second Monday of a month?

Yes. Fugit's README demonstrates mon#2 in the day-of-week field for the second Monday. Verify the exact expression against the Fugit version bundled with your rufus-scheduler release.

How does Fugit combine restricted day-of-month and day-of-week fields?

Fugit follows Vixie cron's OR rule by default: either restricted day field may match. Its documented & suffix opts into AND semantics for those day restrictions.

Timezones and DST

How do I set a timezone with rufus-scheduler?

Put the IANA timezone in the cron string: scheduler.cron('0 9 * * * America/New_York') { ... }. Without an explicit timezone, rufus-scheduler uses the process timezone.

Can a Fugit cron expression include its timezone?

Yes. Fugit documents an IANA timezone after the cron fields, such as 0 9 * * 1-5 America/New_York. Without one, it uses Ruby's provided timezone.

How does DST affect a rufus cron job?

A nonexistent local time can be skipped during spring-forward. During fall-back, Fugit suppresses the duplicate literal occurrence instead of running the same local cron time twice.

Platforms

Should I use rufus-scheduler or sidekiq-cron?

Use rufus-scheduler for in-process, in-memory scheduling and sidekiq-cron for schedules backed by Sidekiq. rufus-scheduler depends on libraries including Fugit and EtOrbi; its schedules live with the application process.

Debugging

How do I prevent overlapping rufus-scheduler jobs?

Pass overlap: false when scheduling the job. If a prior run remains active, rufus-scheduler avoids starting another overlapping instance.

Why does a rufus job run once per Rails worker?

rufus-scheduler is in process, so each application process can create its own scheduler. Run it in one designated process or add leader election.

Crontap

Can Crontap replace an in-process rufus cron?

Yes. You can run an HTTP-backed cron schedule on Crontap; Ruby blocks must be exposed as endpoints, and rufus-specific interval syntax must be translated.

Write the cron here. Run it on Crontap.

Point Crontap at any URL. Pick any cron. Done.

WordPress, Shopify, Railway, Cloud Run, Vercel, HubSpot, Ghost, your own box. If it answers HTTP, Crontap can drive it on a clock you can read, in the timezone that actually matters, and page you when something breaks.

1.9k+ teams · Free forever tier · No credit card