SeqRun Cron Simulator

Cron Simulator — see when your cron job will actually run

A cron expression explainer that shows the real answer: paste any crontab line and get a plain-English translation, the next 10 cron run times in any timezone, and warnings for the daylight saving time and day-of-week traps that quietly break scheduled jobs. Everything runs in your browser.

Type a cron expression, or start with / to describe the schedule in plain English.

How to read a cron expression

┌───────────── minute        0–59
│ ┌─────────── hour          0–23
│ │ ┌───────── day of month  1–31
│ │ │ ┌─────── month         1–12  or JAN–DEC
│ │ │ │ ┌───── day of week   0–7   or SUN–SAT  (0 and 7 are both Sunday)
│ │ │ │ │
* * * * *   command to run

Every cron expression is five fields separated by spaces, read left to right from the smallest unit to the largest. Each field takes * for "every value", a single number, a list such as 1,3,5, a range such as 1-5, or a step such as */15 meaning "every 15th value". The job fires on any minute where all five fields match — with one important exception covered in the next section. So 30 2 * * 1-5 reads as minute 30, hour 2, any day of month, any month, days of week Monday through Friday: 2:30 AM on weekdays.

The day-of-month / day-of-week OR trap

Here is the rule that surprises nearly everyone. When both the day-of-month and the day-of-week fields are restricted — neither one is * — cron combines them with OR, not AND. It is not a bug; it is the documented behaviour of Vixie cron and the crontab on essentially every Linux box.

So 0 0 13 * 5 does not mean "midnight on Friday the 13th". It means "midnight on every 13th of the month, and also midnight on every Friday" — around 64 runs a year instead of the one or two you wanted. When only one of the two fields is restricted, the intuitive AND behaviour applies. To get a true AND, put one constraint in cron and check the other inside the job: schedule 0 0 13 * *, then exit early unless date +%u returns 5. The simulator flags this trap whenever your expression hits it, and the run list above shows you both patterns interleaved.

How daylight saving time breaks cron jobs

Cron matches wall-clock time, and twice a year the wall clock lies. On the spring-forward date, an hour is deleted: in America/Chicago, 2:00 AM jumps straight to 3:00 AM, so a job scheduled at 30 2 * * * has no 2:30 AM to fire at and is silently skipped that day. No error, no log line, just a missing run that someone notices a week later.

On the fall-back date the opposite happens: an hour repeats, so 1:30 AM occurs twice and a job scheduled in that window may run twice. Behaviour differs by scheduler — Vixie cron tries to de-duplicate, but container schedulers and application-level cron libraries frequently do not. The reliable fix is to avoid scheduling anything between 1:00 and 3:00 AM local time, or to run the scheduler on a UTC clock, which has no transitions at all. Switch the timezone picker above to your server's zone and the simulator scans the next 12 months for both hazards using your browser's own timezone database.

Cron and timezones

A cron expression carries no timezone. It is interpreted in the system timezone of whatever machine runs it, and on cloud servers, CI runners, and Docker images that is almost always UTC. This is why 0 9 * * * deployed from a laptop in Berlin fires at 10 AM or 11 AM local, depending on the season, and why the offset moves by an hour twice a year without anyone touching the crontab.

Some schedulers let you pin a zone per job — a CRON_TZ= prefix in the crontab, a TZ setting, or a timezone field in a managed cron product. If yours does not, the honest options are to write your schedules in UTC and accept the local drift, or to schedule at a wall-clock hour where the drift does not matter. This cron timezone converter evaluates your expression in the zone you pick — the wall-clock times a server in that zone would fire at — and shows the matching UTC instants alongside, so you can see both views of the same schedule at once.

Frequently asked questions about cron

What do the 5 fields in a cron expression mean?

A standard cron expression has five space-separated fields, in this order: minute (0-59), hour (0-23), day of month (1-31), month (1-12), and day of week (0-7, where both 0 and 7 mean Sunday). Each field accepts a single number, a list like 1,3,5, a range like 1-5, a step like */15, or * meaning every value. The job runs at every minute where all five fields match the clock, with one exception: the day-of-month and day-of-week fields are combined with OR rather than AND when both are restricted.

Why didn't my cron job run?

The three common causes are a wall-clock time that does not exist on the spring-forward daylight saving date, a day-of-month value like 31 in a month that is shorter than that, and a server whose timezone is not the timezone you had in mind. Paste your expression above and switch the timezone picker to your server's timezone: the simulator lists the exact dates a run is skipped. Cron only fires when the clock actually reaches the scheduled time, so a time that is skipped by a DST jump is simply never reached.

Why did my cron job run twice?

On the autumn fall-back date, the clock is wound back and one hour of wall-clock time happens twice. A job scheduled inside that repeated hour can fire on both passes, depending on which scheduler you use. Vixie cron and most Linux distributions try to run such jobs only once, but container schedulers, application-level schedulers, and cloud cron products vary widely. The safest fix is to schedule outside the 1:00-3:00 AM window entirely, or to run the job on a UTC clock.

What timezone does cron use?

Classic Unix cron uses the system timezone of the machine it runs on, which on most cloud servers and containers is UTC. That means 0 9 * * * is 9 AM UTC, not 9 AM where you live, and the gap shifts by an hour twice a year if your local timezone observes daylight saving time. Some schedulers let you set a timezone per job, such as the CRON_TZ prefix or a TZ setting in the crontab. Use the timezone picker above to see what your expression means in whichever timezone the job will actually run.

How do I run a cron job on the last day of the month?

Standard cron cannot express "the last day of the month" because the day-of-month field only takes fixed numbers. The portable workaround is to schedule 0 0 28-31 * * so the job wakes on every candidate day, then exit immediately inside the job unless tomorrow is the first of the month. Some extended implementations, such as Quartz, support an L character for this, but it is not available in Vixie cron or the crontab on a typical Linux server.

Does 0 0 13 * 5 run only on Friday the 13th?

No. When both the day-of-month and the day-of-week fields are restricted, cron combines them with OR, not AND. So 0 0 13 * 5 runs at midnight on every 13th of the month and also at midnight on every Friday, which is roughly 60 runs a year rather than one or two. To run only on Friday the 13th, put one constraint in cron and check the other inside your job, for example schedule 0 0 13 * * and exit early unless the weekday is Friday.

What does */15 mean in cron?

The slash is a step operator, so */15 in the minute field means every 15th minute starting from 0: minutes 0, 15, 30 and 45 of every hour. Steps apply to whatever range precedes them, so 1-30/5 means every fifth minute between 1 and 30. Note that steps restart at the top of each hour rather than running continuously, so */40 fires at minute 0 and minute 40 and then jumps back to 0, giving a 20-minute gap across the hour boundary.

Is 0 the same as 7 in the cron day-of-week field?

Yes. The day-of-week field accepts 0 through 7, and both 0 and 7 mean Sunday, which lets you write ranges like 1-7 for Monday through Sunday. You can also use the three-letter English abbreviations SUN through SAT, so MON-FRI is identical to 1-5. Day names are not case sensitive, but they cannot be mixed with numbers inside a single range.

SeqRun is coming

Scheduled jobs that run in your timezone, survive daylight saving time, and tell you when a run is skipped. Leave your email and we will let you know when it opens.