Describe any cron schedule in plain English and see the next five runs. Client-side only — nothing you type leaves your browser.
Cron expression
This schedule means
Every 15 minutes.
| Field | Value | Allowed |
|---|---|---|
| Minute | */15 | 0-59 |
| Hour | * | 0-23 |
| Day of month | * | 1-31 |
| Month | * | 1-12 |
| Day of week | * | 0-6 (Sun-Sat) |
Next 5 runs (your local timezone)
Calculating…
Common schedules
Pro tip
Cron runs in the server's timezone, not yours. If a job fires an hour off twice a year, the schedule is fine — the box is on local time and just crossed a DST boundary. Set TZ=UTC in the crontab and the problem disappears.
Type an expression in the box and the description updates as you type — there is no submit button, because waiting for a click to learn that you typed 0 0 * * 8 helps nobody. Every keystroke re-parses the five fields, rewrites the plain-English summary, and recalculates the next five times the job would actually fire on your machine. Click any preset to load a known-good schedule and edit from there.
The next-run list is the part worth reading twice. A description tells you what you asked for; the run times tell you what you will get. Those two disagree more often than people expect, and the gap is almost always in the day fields.
A standard crontab line is five space-separated fields followed by the command to run. Left to right they are minute, hour, day of month, month, and day of week. Each accepts a number, a list (1,15), a range (1-5), a step (*/10), or * for every value. Month and day-of-week also take three-letter names, so 0 9 * * MON and 0 9 * * 1 are the same schedule.
Sunday is both 0 and 7. That is not a quirk of this tool — Vixie cron, the implementation behind crontab -e on essentially every Linux box, accepts either and treats them identically. This tool normalises 7 to 0 so the day breakdown below shows one value instead of two names for the same day.
Here is the rule that catches experienced people: when you restrict both the day-of-month field and the day-of-week field, cron runs the job when either matches, not when both do. So 0 0 13 * FRI does not mean "Friday the 13th". It means midnight on the 13th of every month, plus midnight every Friday — roughly five times the runs you intended.
If one of the two fields is *, the fields combine the way you would expect. The OR behaviour only appears when both are narrowed. Paste that expression above and look at the next-run list: the dates will not all be Fridays, and they will not all be the 13th. Seeing it beats being told it.
Most real crontabs are shorter than the syntax suggests. Log rotation and cache warming land on 0 * * * *. Nightly database dumps sit at 0 3 * * *, chosen because 3am is after the batch jobs and before the morning traffic. Weekday report emails use 0 9 * * 1-5. Certificate renewal checks run twice daily on 0 0,12 * * * because that is what certbot's own documentation suggests.
The schedules that go wrong are the clever ones. A job on */7 * * * * does not run every seven minutes — it runs at :00, :07, :14 … :56, then jumps four minutes to the next hour's :00. Steps restart at the top of each field's range, so any step that does not divide evenly into 60 produces an uneven gap once an hour.
Cron uses the timezone of the machine it runs on. If that machine is on local time and observes daylight saving, a job scheduled for 2:30am will run twice on the day the clocks go back and not at all on the day they go forward. Nothing about the expression is wrong; the hour simply does not exist that day.
The fix most teams settle on is putting TZ=UTC at the top of the crontab and doing the mental arithmetic once, rather than debugging a twice-a-year off-by-one forever. The next-run times above are calculated in your browser's timezone, which is a useful sanity check but is not necessarily your server's.
Cron accepts a handful of shorthand macros in place of all five fields: @yearly and @annually (both 0 0 1 1 *), @monthly, @weekly, @daily and its alias @midnight, and @hourly. Type any of them above and the tool expands it to the five-field form so you can see what it really means.
@reboot is the exception. It fires once when the machine starts and has no recurring schedule at all, so there is nothing to predict — the tool says so rather than inventing run times.
Quartz — the Java scheduler — and a few other systems extend the format with L for last-day, W for nearest-weekday, and # for nth-weekday-of-month. They are genuinely useful and they are not part of Unix cron. Accepting them here would tell you an expression is valid on a box where crontab will reject it, so this tool names the extension instead.
Six-field expressions get the same treatment. Quartz and Spring put seconds in front, Unix cron does not, and the difference is one silent factor-of-sixty in how often your job runs. If you paste six fields the tool tells you which one to drop.
Everything here runs in your browser. The parser is a few hundred lines of JavaScript shipped with the page — no request is made when you type, and no expression is logged anywhere. Open the Network tab in DevTools and type: nothing moves.
The description and run times recalculate on every keystroke, so there is no "run" shortcut to press. Ctrl+Enter copies the expression itself, ready to paste into a crontab. Ctrl+Shift+C copies the next five run times, which is the thing worth pasting into a pull request when someone asks what the schedule does.
Five space-separated fields that tell a Unix scheduler when to run something: minute, hour, day of month, month, day of week. The expression 0 9 * * 1-5 means 9am on weekdays. Everything after those five fields is the command itself, not part of the schedule.
No, and this is the single most expensive misreading of the format. When both the day-of-month and day-of-week fields are restricted, cron runs the job when either one matches — so that expression fires on the 13th of every month and on every Friday. Paste it into the box above and read the next-run dates.
Steps restart at the beginning of each field's range rather than counting continuously. A */7 minute field fires at :00, :07, :14 and so on up to :56, then the hour rolls over and the next run is :00 — four minutes later, not seven. Any step that does not divide evenly into 60 does this.
Both. Vixie cron, which is what crontab -e uses on nearly every Linux distribution, accepts either value for Sunday and treats them the same. This tool normalises 7 to 0 so the breakdown shows one day instead of appearing to list Sunday twice.
Your browser's, which is shown above the list. Your server almost certainly uses its own, and that mismatch is where scheduled jobs quietly drift. Most teams end up setting TZ=UTC at the top of the crontab so the schedule stops moving twice a year with daylight saving.
Daylight saving. On the day clocks go back, 2:30am happens twice and cron fires on both; on the day they go forward, 2:30am never exists and the job is skipped entirely. The expression is not the problem — the machine's local time is. Schedule anything that matters outside the 1am-3am window, or run the box on UTC.
Because standard Unix cron does not understand them. Those are Quartz extensions for last-day-of-month, nearest-weekday, and nth-weekday. Accepting them here would tell you an expression is fine on a machine where crontab will refuse it, so the tool names the extension instead of guessing.
Six fields means the first one is seconds, which is a Quartz and Spring convention rather than a Unix one. Feeding a six-field expression to Unix cron shifts every field one position left, so a job you meant to run hourly runs every minute. Drop the leading seconds field.
@hourly is 0 * * * *, @daily and @midnight are 0 0 * * *, @weekly is 0 0 * * 0, @monthly is 0 0 1 * *, and @yearly and @annually are both 0 0 1 1 *. Type any of them above and the tool shows the five-field form. @reboot is different — it fires at boot and has no recurring schedule at all.
Nothing you type is transmitted. The parser is JavaScript that ships with the page and runs entirely in your browser, so there is no request to inspect and no log to leak. Open the Network tab in DevTools and type an expression — you will see no traffic.
Ctrl+Enter copies the expression and Ctrl+Shift+C copies the next five run times. There is no shortcut to trigger a calculation because the description and run list update on every keystroke.
You can, and plenty of teams run nightly static analysis that way. Git AutoReview takes a different approach — reviews trigger on the pull request itself inside VS Code, so feedback arrives while the author is still in the change rather than in a 3am batch report nobody opens.
Developer Toolkit by Git AutoReview
Free tools for developers. AI code review for teams.