Cron Expression Generator
Build or decode a cron schedule, read it in plain English, see the next five runs. 100% free, no signup. Everything runs in your browser.
Loading the tool…
This cron expression generator builds a schedule from plain dropdowns: every minute, hourly, daily at a set time, weekly on the days you pick, monthly on a date, or a custom expression if you already know what you want. It shows the five-field expression, reads it back to you in plain English, and lists the next five times the job would actually run. You can also paste an existing expression and have it explained instead, which is how most people arrive here.
It supports the standard five fields along with lists, ranges and step values, so 0 9 * * 1-5 and */15 * * * * both work and both get explained. Everything runs in your browser with nothing uploaded, which is worth saying because cron lines often carry the shape of internal systems in them. If you are also wrestling with timestamps in logs, the epoch timestamp converter is the companion tool.
How to use
- Pick a schedule type from the dropdown, from every minute through to monthly on a specific date.
- Fill in the details that appear, such as the hour and minute, or which days of the week.
- Read the generated expression and the plain English sentence underneath it.
- Check the next five run times and confirm they land where you expected.
- Switch to the custom option if you need lists, ranges or step values the dropdowns do not cover.
- To decode instead of build, paste an existing expression and read the explanation and upcoming runs.
- Copy the expression into your crontab, scheduler or config file, then verify it against your platform's docs.
Why use our cron expression generator?
I built this after a backup job silently did not run for eleven days. The expression was syntactically valid, my mental reading of it was wrong, and nothing in the system had any reason to complain. That is the specific danger of cron: a bad schedule is not an error, it is just silence. The next five run times exist entirely because of those eleven days, and they are the first thing I look at now, before the expression itself.
The one I got wrong first, and the one that catches nearly everyone, is what happens when you restrict both day of month and day of week. You would reasonably read 0 0 1 * 1 as midnight on the first of the month when it falls on a Monday. Standard cron treats it as an or, so it fires on the first of every month and on every Monday. Seeing the next five run times land on dates you never intended is a much faster lesson than reading the rule.
Reading an expression back in plain English matters more than generating one. Most of the time you are not writing a new schedule, you are looking at a line somebody left in a config file three years ago and trying to decide whether it is safe to change. Paste it in, read the sentence, look at the upcoming runs, and you know what it does without deploying anything to find out.
This is standard five-field cron and I say so plainly. Some systems add a seconds field at the front, some add a year field at the end, and special strings like @reboot, @daily and @yearly are scheduler-specific rather than universal. Quartz, systemd timers and various cloud schedulers all differ. The crontab manual page is the reference for the classic Unix behavior this follows, and your own platform's documentation is the final word before you paste anything into production.
What I refuse to do is guess your server's timezone. The next run times are shown in your browser's local time, because that is the only clock I can actually see. Your cron daemon runs on whatever the server or container is set to, which is very often UTC, and that gap is responsible for a good share of jobs that run exactly the right number of hours away from where they were wanted. When the two differ, the time zone converter does the translation properly, including the daylight saving edge that trips people up twice a year.
Who is this tool for?
The most common case is a weekday morning job. You want a report generated at 9:00 am Monday through Friday, and you want to be sure it does not fire on Saturday. Pick weekly, check the five days, and the expression comes out as 0 9 * * 1-5 with five upcoming timestamps that visibly skip the weekend. That check takes two seconds and removes the doubt entirely.
Decoding legacy schedules is the other half of the traffic. Someone inherits a server, opens the crontab, and finds a dozen lines nobody has explained since the person who wrote them left. Pasting each one in and reading the plain English version turns an intimidating file into an inventory in about five minutes, which is usually the first honest step before touching anything.
Developers building a config that ships with defaults use it to sanity check the values they are about to hard-code. Backups nightly, cache warming every 15 minutes, a cleanup task on the first of the month: each of those is a one line decision that is expensive to get wrong and cheap to verify. It sits next to the regex tester in my browser for exactly the same reason, since both are syntaxes that fail quietly rather than loudly.
It is also useful for spreading load. If six jobs all run at 0 0 * * *, they all hit the database at once at midnight. Staggering them to 0, 10, 20 and so on across the hour is trivial to express and easy to check here, and it turns a nightly spike into something the machine barely notices.
Frequently asked questions
Minute, hour, day of month, month, and day of week. Minutes run 0 to 59, hours 0 to 23, day of month 1 to 31, month 1 to 12, and day of week 0 to 6 with 0 as Sunday. Many implementations also accept 7 for Sunday and three letter names for months and days.
Use a step value in the minute field: */15 * * * * fires at :00, :15, :30 and :45 of every hour. The generator will produce it for you, and the next run times confirm the spacing at a glance.
Because standard cron treats a restricted day of month and a restricted day of week as an or, not an and. An expression meaning the first of the month and Monday actually fires on both. If you truly need the intersection, schedule it daily and put the date check inside your script.
Your browser's local timezone, since that is the only clock available in the page. Your scheduler runs in the server or container timezone, which is frequently UTC. Check that setting before trusting the times, and convert if the two differ.
No, and that is deliberate. Those shorthands are scheduler-specific rather than part of the five-field syntax, and @reboot in particular behaves differently across systems. The tool sticks to expressions that mean the same thing in the widest range of places.
Not directly. Some platforms add a seconds field at the front or a year field at the end, and pasting a five-field expression into a six-field parser shifts every value one position, which produces a schedule that is valid and completely wrong. Check your platform's docs and adjust.
No. Parsing and the run time calculation happen entirely in your browser, with nothing uploaded and nothing logged. Cron lines often reveal internal paths and job names, so keeping them local is the only sensible default.
Yes. Home automation, backup software, task runners and plenty of consumer apps accept cron syntax now. If you are generating identifiers for those scheduled jobs as well, the UUID generator sits one click away.

