Cron Expression Generator
What cron expression runs my job at the right time?
Turn a plain schedule into a cron expression you can paste directly into your crontab, CI config, or cloud scheduler. Set frequency, time, and day fields — the tool assembles the five-field expression and explains when it runs.
—
Send feedback
💡 Share your idea or report a problem
✓ Thanks! We'll take a look.
Learn more
How It Works
The formula, explained simply
Every cron daemon is essentially a clock watcher. Once per minute it wakes up, reads the current time, and scans every entry in the crontab. For each entry it asks one question: do all Minute: 0 | Hour: 9 | Day of month: * | Month: * | Day of week: * fields match right now? If yes, it spawns the job. If no, it goes back to sleep. The whole system is stateless — it has no memory of when a job last ran, no concept of missed windows, and no backfill logic.
The five positional fields form a coordinate in time-space. Think of them as nested sieves. The month field filters down to one or more months per year. The day-of-month and day-of-week fields filter further to specific calendar dates. The hour and minute fields pin the exact moment within that day. A job only fires when the current timestamp passes through all five sieves at once. That AND logic is the entire engine.
Special characters extend what the position system can express. The asterisk (*) removes a sieve entirely, passing every value through. A slash (/) creates a step pattern — */5 passes 0, 5, 10, 15, and so on. Commas allow multiple discrete values ( 1,15,30 in the minute field fires three times per hour). Hyphens define contiguous ranges (1-5 in the day-of-week field means Monday through Friday). These four characters cover the vast majority of real scheduling needs without any programming logic.
When To Use This
Right tool, right situation
Use a cron expression when the job needs to fire on a clock-based schedule that repeats indefinitely: database backups, log rotation, cache warming, report generation, health checks, and similar periodic tasks. Cron is well-suited when the job is idempotent — running it twice accidentally causes no harm — because cron provides no duplicate-suppression and no missed-window recovery.
Cron is not the right tool when job timing depends on events rather than the clock. If a job should run after a user completes a purchase, after an upstream data pipeline finishes, or after a file arrives in a directory, an event-driven queue or workflow orchestrator handles the dependency relationship better than any time expression can. Similarly, for jobs that need sub-minute precision, standard five-field cron is insufficient — some extended implementations add a seconds field, but it is non-standard and not portable across daemons.
Also reconsider cron when the schedule needs to respect business-day logic (skip holidays, skip weekends dynamically based on a calendar) or when the job must not overlap with its own previous run. A cron daemon does not check whether the previous invocation finished before starting the next one. A job that occasionally runs longer than its interval will stack up concurrent processes. For overlap protection, use a wrapper that checks a lock file or a dedicated job scheduler that understands run duration.
Common Mistakes
Why results sometimes look wrong
Mistake: setting both day-of-month and day-of-week to non-wildcard values. Most POSIX cron implementations treat this combination as OR, not AND. A job with DOM= 15 and DOW=5 fires on the 15th of every month and also every Friday — potentially far more often than intended. The safe rule: pin one of the two day fields and leave the other as an asterisk. Only use both when you genuinely want the union of both conditions.
Mistake: assuming the server uses your local timezone. Cron daemons run in the timezone of the server process, not the user who wrote the expression. A daily job set to run at hour 9 fires at 9 AM server time, which may be 2 AM or 5 PM in the developer's local time depending on their location and whether the server is set to UTC. Always confirm the daemon timezone before deploying time-sensitive jobs — most production servers run UTC specifically to avoid this confusion.
Mistake: not accounting for months with fewer than 31 days. A monthly job with DOM=31 silently skips February, April, June, September, and November — those months never have a 31st day, so the cron condition is never satisfied. For reliably end-of-month execution, use application logic rather than a fixed DOM value, or accept that the job will run on the last day only in 31-day months.
The Math
Worked examples and deeper derivation
A cron expression is a five-tuple: M H DOM MON DOW. Each position has a defined integer range. The minute field (M) accepts integers from 0 through 59. The hour field (H) accepts 0 through 23 in 24-hour format. Day of month (DOM) accepts 1 through 31. Month (MON) accepts 1 through 12. Day of week (DOW) accepts 0 through 6, with 0 and 7 both representing Sunday in most implementations.
For the example schedule of daily at 09:00, the generator fills the fields as: minute = 0, hour = 9, day-of-month = wildcard, month = wildcard, day-of-week = wildcard. The resulting five-tuple is 0 9 * * *. The daemon evaluates this as: current_minute == 0 AND current_hour == 9 AND TRUE AND TRUE AND TRUE. The expression collapses to a single truth check on minute and hour, satisfied exactly once every 24-hour cycle.
For the weekly Friday case from the worked examples — 0 9 * * * using the weekly Friday inputs — the evaluation becomes: current_minute == 0 AND current_hour == 9 AND TRUE AND TRUE AND current_dow == 5. This is satisfied once per week. The field breakdown Minute: 0 | Hour: 9 | Day of month: * | Month: * | Day of week: * shows exactly which positions carry constraints and which pass everything through with an asterisk. Reading left-to-right across the five fields tells you the full firing rule in one glance once you know the positional order.
Expert Unlock
The thing most explanations skip
The standard five-field cron format has a documented ambiguity in the day-of-month and day-of-week interaction: Vixie cron (the reference implementation) uses OR when both are specified as non-wildcards, but this is not universal. Cloud schedulers including AWS EventBridge and GCP Cloud Scheduler treat the same combination differently and document their own behavior explicitly — always verify against your specific platform's documentation rather than assuming POSIX behavior. A second edge case: some platforms count weeks differently from POSIX (ISO week numbering starts on Monday, POSIX week numbering starts on Sunday), and expressions built for one may fire on a different day on the other. When portability matters, stick to hour and minute as the only non-wildcard fields and handle all date-selection logic inside the job itself.
What does each field in my cron expression actually control?
Need something this doesn't cover?
Suggest a tool — we'll build it →