Metronome logo

Rust · single binary · cron

A cron scheduler in Rust
you can actually unit test.

Metronome is a single-binary cron-style job scheduler. No daemon, no global state, no root-owned crontab. The schedule logic is a pure library function, fully unit tested, that you can embed in your own project.

View on GitHub Try the demo

next fire times, computed live in your browser

How to use this playground

Type a five-field cron expression (minute, hour, day-of-month, month, day-of-week) into the box, or click a preset. The list updates live with the next fire times computed in your browser by the same schedule engine the binary uses. Try steps like */15, ranges like 1-5, and lists like 1,3,5.

See the schedule before it runs.

Ask for the next fire times of any expression, or validate a whole jobs file, without waiting for a single tick.

$ metronome next "*/15 * * * *" --count 5
2026-09-07 09:00:00 Mon
2026-09-07 09:15:00 Mon
2026-09-07 09:30:00 Mon
2026-09-07 09:45:00 Mon
2026-09-07 10:00:00 Mon

$ metronome check --file jobs.metro
2 job(s) OK

real CLI output. the browser demo above computes the same fire times with the same engine

Why it is different

A schedule engine you can trust because you can test it directly.

Pure schedule engine

next_after(expr, now) is a plain function with no I/O and no shared state. Test it directly, no clock mocking required.

One static binary

No daemon to install, no system-wide crontab to edit as root. Point it at a text file and run.

Embeddable library

Pull in the metronome crate and call the parser and next_after from your own Rust code and your own tests.

Cron syntax supported

FieldRange
minute0-59
hour0-23
day-of-month1-31
month1-12
day-of-week0-7 (0 and 7 both mean Sunday)

Every field accepts the same five operators. They compose, so 1-30/2 is a step over a range and 1,3,5 is a list.

*

Any value in the field's full range.

1-5

A contiguous range, low to high.

*/15

A step over the full range: every 15th value.

1-30/2

A step over a range: every 2nd value from 1 to 30.

1,3,5

A list of single values or ranges.

day-of-month OR day-of-week

When both are restricted, a day fires if it satisfies either, matching standard cron.

Two surfaces, one crate.

Run it as a binary, or embed the engine and test your own schedules in your own tests.

next

Print the next N fire times for an expression, so you can eyeball a schedule before committing it.

check

Validate a jobs file without running it, so a bad expression fails in review, not at 3am.

run

Sleep until each job is due, then run it in-process. No daemon, no root-owned crontab.

library

Pull in the metronome crate and call CronExpr::parse and next_after directly from your own Rust code.

metronome next "*/15 * * * *" --count 5
metronome check --file jobs.metro
metronome run --file jobs.metro