Cron schedule syntax
CronRadar reads each job's schedule as a standard five-field cron expression. The schedule decides when the next run is due, when a late run becomes critical, and which price class the job is in. Framework integrations translate their scheduler's native schedules; with a base SDK or raw HTTP, you send the expression yourself.
Format
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12 or JAN-DEC)
│ │ │ │ ┌───────────── day of week (0-6 or SUN-SAT; Sunday is 0)
│ │ │ │ │
0 2 * * *| Syntax | Example | Meaning |
|---|---|---|
| Any value | * * * * * | Every value of the field |
| List | 0 6,18 * * * | 06:00 and 18:00 |
| Range | 0 9 * * 1-5 | Monday through Friday |
| Step | */15 * * * * | Every 15 minutes, starting at :00 |
| Range with step | 0 9-17/2 * * * | 09:00, 11:00, 13:00, 15:00, 17:00 |
| Value with step | 5/20 * * * * | :05, :25, :45 |
| Names | 0 0 1 JAN *, 0 9 * * MON-FRI | Month and weekday names or their first three letters, in any case |
Pass the expression URL-encoded in schedule on a job's first check-in, or in monitors[].schedule for discovery sync. See the HTTP API reference.
curl --fail-with-body --silent --show-error \
--user "$CRONRADAR_API_KEY:" \
"https://cron.life/api/v1/ping/nightly-backup?schedule=0%202%20*%20*%20*&gracePeriod=900"Not accepted
A check-in with one of these schedules is rejected with 400 INVALID_REQUEST and an Invalid schedule format message. Discovery sync reports the monitor in errors and processes the rest.
| Not accepted | Example | Use instead |
|---|---|---|
| A seconds field | 0 0 2 * * * | 0 2 * * * |
| A year field | 0 2 * * * 2026 | 0 2 * * * |
? | 0 2 ? * 1-5 | 0 2 * * 1-5 |
| Shortcuts | @daily, @hourly | 0 0 * * *, 0 * * * * |
L, W, # | 0 9 L * *, 0 9 * * 1#1 | See the note below the table |
7 for Sunday | 0 9 * * 7 | 0 9 * * 0 |
There is no five-field way to write "the last day of the month" or "the nearest weekday". Schedule the job on every candidate date and let it decide whether to do the work, checking in on every scheduled invocation, including the ones that exit early. For the last day of the month, that is 0 9 28-31 * * plus a check that tomorrow is the 1st. For "the first Monday", see the next section.
Both day fields must match
When both day of month and day of week are restricted, CronRadar expects a run only on dates that match both. Linux cron runs on dates that match either, so the same expression can mean different things to your scheduler and to CronRadar.
| Expression | CronRadar expects | Linux cron runs |
|---|---|---|
0 9 1 * 1 | 09:00 on the 1st, only when it is a Monday | 09:00 on every 1st and every Monday |
0 9 1-7 * 1 | 09:00 on the first Monday of the month | 09:00 on the 1st through 7th and every Monday |
To monitor a crontab entry that restricts both fields, split it into two entries, one for the day of month and one for the day of week, each reporting to its own job key.
Time zone
CronRadar evaluates every schedule in UTC. The application's time zone setting does not change when a run is expected. Write the schedule in UTC: a job that runs at 02:00 on a server set to UTC+2 is 0 0 * * *.
If the job's scheduler follows daylight saving time, its UTC run time moves by an hour twice a year. Run the scheduler in UTC where you can. Otherwise, use the earlier of the two UTC times and a grace period of at least an hour plus the job's usual duration. For a job at 02:00 in New York, that is 0 6 * * * with gracePeriod of at least 3600.
Framework integrations
Framework integrations translate scheduler-native schedules when the meaning survives. Quartz.NET's six-field expressions are converted, so 0 0 2 * * ? becomes 0 2 * * *. A schedule that five fields cannot express, such as one that runs more than once a minute, is logged and that job is not monitored. Check each integration guide for its limits.
Schedule and price class
On Grow, each paid monitor's price class comes from the shortest gap between runs in its schedule. See pricing.
| Class | Shortest gap | Example |
|---|---|---|
| Fast | Under 5 minutes, or a schedule that can't be read | * * * * * |
| Frequent | 5 to 59 minutes | */15 * * * * |
| Standard | An hour or more | 0 0 1 */2 * |
Examples
| Schedule | Expression |
|---|---|
| Every 5 minutes | */5 * * * * |
| Every hour, on the hour | 0 * * * * |
| Every day at 02:00 UTC | 0 2 * * * |
| Weekdays at 09:00 UTC | 0 9 * * 1-5 |
| First Monday of the month at 09:00 UTC | 0 9 1-7 * 1 |
| 1st of every month at 00:00 UTC | 0 0 1 * * |
| Every 2 months, on the 1st at 00:00 UTC | 0 0 1 */2 * |
| Every quarter, on the 1st at 00:00 UTC | 0 0 1 */3 * |
0 0 1 */2 * runs in January, March, May, July, September, and November. The first-Monday expression only means that to CronRadar; your scheduler may read it differently, as described above. For the general cron syntax and how other schedulers differ, see cron expression syntax. To build an expression and preview its next runs, use crontab.space.