Development

Cron Generator

Generate cron expressions easily with a visual builder. Get human-readable descriptions of your schedule.

Advertisement

What Is a Cron Expression

A cron expression is a string that encodes a recurring schedule using five (or sometimes six) fields separated by whitespace. Each field specifies a time unit — minute, hour, day of month, month, and day of week — and the scheduler fires the associated command whenever all fields match the current time. Cron is the backbone of task scheduling on Unix-like systems and is widely supported by cloud platforms, job queues, and application frameworks.

The format was originally designed for the Vixie cron daemon in the 1980s, and its syntax has remained remarkably stable because it elegantly expresses a huge range of schedules in a compact form. A single expression can describe everything from "every minute" to "the third Friday of every quarter." Understanding the syntax and its quirks is essential for anyone responsible for scheduled jobs, backups, report generation, or periodic data pipelines.

Despite its power, cron syntax is famously tricky for newcomers. Field ranges differ (minutes are 0-59, hours 0-23, months 1-12), the day-of-month and day-of-week fields interact in non-obvious ways, and subtle mistakes can cause jobs to run at the wrong time or far more often than intended. A cron generator and validator eliminates the trial-and-error approach by letting you visualize the schedule and confirm the next several firing times before deploying.

  • Five fields: minute, hour, day of month, month, day of week
  • Encodes recurring schedules in a compact, declarative string
  • Originally from Vixie cron; widely supported across platforms
  • Subtle syntax mistakes can cause jobs to fire at the wrong time

The Five Fields and Their Ranges

Each field in a cron expression has a specific allowed range and accepts numbers, ranges, lists, step values, and wildcards. The first field is minute (0-59), the second is hour (0-23), the third is day of month (1-31), the fourth is month (1-12 or JAN-DEC), and the fifth is day of week (0-6 or SUN-SAT, where 0 or 7 is Sunday). Some implementations add a sixth field for seconds at the front, and some add a year field at the end.

An asterisk (`*`) in a field means "every value" — so `* * * * *` runs every minute. A single number pins that field to a specific value: `30 2 * * *` runs at 02:30 every day. A range like `1-5` matches values inclusively, and is commonly used in the day-of-week field to mean Monday through Friday. A list like `0,15,30,45` matches any of the listed values, useful for expressing irregular schedules.

Step values are written with a slash: `*/15` in the minute field means "every 15 minutes," and `0-23/2` in the hour field means "every 2 hours starting at 0." Step values are a powerful way to express periodic schedules compactly, but be careful with day-of-month steps — `*/2` does not mean every other day across months; it means days 1, 3, 5, ..., 31 within each month, which can cause unexpected behavior at month boundaries.

  • 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)
  • Asterisk (*) means every value in that field
  • Ranges (1-5), lists (1,3,5), and steps (*/15) compose complex schedules

Common Cron Patterns Every Developer Should Know

Certain schedules come up repeatedly in real-world systems, and recognizing the canonical patterns saves time and prevents mistakes. `0 * * * *` runs at the top of every hour, `0 0 * * *` runs at midnight every day, and `0 0 * * 0` runs at midnight every Sunday — the classic weekly backup slot. For end-of-month reports, `0 0 1 * *` runs at midnight on the first of every month.

For business-hours schedules, `0 9 * * 1-5` runs at 09:00 Monday through Friday, and `0 9,12,17 * * 1-5` runs three times a day on weekdays. For monitoring or heartbeat jobs, `*/5 * * * *` runs every five minutes. For quarterly reports, `0 0 1 1,4,7,10 *` runs at midnight on the first of January, April, July, and October. These patterns cover the vast majority of scheduling needs in operations and reporting.

Be careful with two specific patterns. First, "last day of month" is not natively expressible in standard cron — you need a workaround like `L` in some extended implementations or a runtime check inside the job. Second, the day-of-month and day-of-week fields are OR'd together when both are restricted (not `*`), which is a frequent source of confusion. The expression `0 0 13 * 5` does not mean "midnight on Friday the 13th"; it means "midnight on the 13th OR any Friday," which fires far more often than intended.

  • 0 * * * * — top of every hour
  • 0 0 * * 0 — midnight every Sunday (weekly backup)
  • 0 9 * * 1-5 — 09:00 every weekday (business hours)
  • */5 * * * * — every five minutes (monitoring)
  • 0 0 1 1,4,7,10 * — quarterly reports on the 1st of Jan/Apr/Jul/Oct

Debugging and Validating Cron Schedules

Cron mistakes are notoriously hard to catch because a wrong schedule may run successfully but at the wrong time, producing subtle operational issues that surface only days or weeks later. The most reliable way to validate a cron expression is to compute the next several firing times and confirm they match your intent. A good cron generator shows you the next 5-10 firing times in plain English so you can verify visually.

Common bugs include off-by-one errors in the day-of-week field (where 0 and 7 both mean Sunday in many implementations), timezone confusion between the scheduler's clock and the developer's local time, and the day-of-month/day-of-week OR interaction described above. Always confirm the timezone in which the scheduler runs — production servers are often set to UTC, which can shift expected firing times by several hours relative to your local clock.

Another subtle issue is daylight saving time. In regions that observe DST, jobs scheduled between 02:00 and 03:00 may fire twice, not at all, or at unexpected times during the transition. For critical jobs, avoid scheduling during the DST transition window or use UTC throughout your infrastructure to sidestep the issue entirely. Document the expected timezone in your deployment configuration so operators can quickly diagnose timing issues.

  • Compute the next 5-10 firing times and verify in plain English
  • Day-of-week 0 and 7 both mean Sunday in many implementations
  • Confirm the scheduler's timezone (often UTC in production)
  • Avoid scheduling critical jobs during DST transition windows
  • Document the expected timezone in deployment configuration

Cron in Modern Environments

While traditional cron runs on a single host, modern distributed systems use a variety of cron-like schedulers with their own dialects and capabilities. Kubernetes CronJobs, AWS EventBridge, Cloud Scheduler, Azure Functions timers, and cron-like features in job queues (Celery, Sidekiq, BullMQ) all accept cron expressions but may add a sixth field for seconds or extend the syntax with features like `L` (last day) and `#` (nth weekday of month).

When moving cron expressions between systems, verify the field count and supported syntax. A five-field expression that works on a Linux host may fail in a system that expects six fields, and advanced features like `L` and `?` are not portable across all engines. Test the expression in the target environment rather than assuming compatibility.

For distributed systems, traditional cron has a significant limitation: it runs on a single host and has no built-in locking or coordination. If you run the same cron expression on multiple replicas, the job fires on all of them simultaneously, causing duplicate work or race conditions. Use a distributed lock (Redis, database advisory lock) or a dedicated scheduler like Airflow, Prefect, or a cloud managed service to coordinate execution across replicas.

  • Kubernetes CronJobs, AWS EventBridge, and Cloud Scheduler accept cron syntax
  • Some add a seconds field or extend syntax with L and #
  • Verify field count and supported syntax when porting expressions
  • Traditional cron has no distributed locking — handle it yourself
  • Use Airflow, Prefect, or managed schedulers for distributed coordination

Best Practices for Reliable Cron Jobs

Reliable cron jobs are more than a correct expression; they require thoughtful design around idempotency, observability, and failure handling. Make every cron job idempotent so that running it twice produces the same result as running it once. This protects against the duplicate firings that occur during deployments, restarts, or clock drift, and it makes retries safe.

Always log the start, end, and outcome of each job run, and surface failures to a monitoring system rather than letting them silently disappear into a log file. A cron job that fails silently for weeks can cause significant data loss or staleness before anyone notices. Hook failures into alerting (PagerDuty, Slack, email) with clear escalation rules, and include enough context in the alert to diagnose the issue without SSHing into the host.

Finally, be conservative with frequency and duration. A job that runs every minute but takes 90 seconds to complete will eventually overlap itself and exhaust resources. Set a timeout on each run, use a lock to prevent overlapping executions of the same job, and prefer slightly less frequent schedules with more headroom over tight schedules that leave no margin for slowness. Periodically review your cron schedule as a whole to catch jobs that are no longer needed or that could be consolidated.

  • Make jobs idempotent so duplicate runs are safe
  • Log start, end, and outcome of every run
  • Alert on failures — never let them disappear silently
  • Set timeouts and use locks to prevent overlapping executions
  • Periodically review and prune the full cron schedule