This cron expression guide gives you a repeatable way to build, test, and troubleshoot scheduled jobs across servers, containers, CI workflows, and cloud platforms. Use the checklists to avoid ambiguous schedules, timezone surprises, missed runs, and duplicate work.
Overview
A cron expression describes when a recurring task should run. In the traditional Unix format, it usually contains five time fields followed by a command:
minute hour day-of-month month day-of-week command
The five fields are interpreted as follows:
| Field | Allowed values | Examples |
|---|---|---|
| Minute | 0–59 | 0, 15, */10 |
| Hour | 0–23 | 2, 18, */4 |
| Day of month | 1–31 | 1, 15, 1-7 |
| Month | 1–12 | 1, 6-8, * |
| Day of week | Platform-dependent, commonly 0–6 or 1–7 | 1-5, 0, MON-FRI |
Common operators include an asterisk for every permitted value, a comma for a list, a hyphen for a range, and a slash for an interval. For example, */15 means every 15 units within that field, while 9-17 means values from 9 through 17.
These expressions are not completely portable. Linux cron, Kubernetes CronJobs, GitHub Actions, and managed cloud schedulers can differ in field count, supported syntax, timezone defaults, and handling of overlapping runs. Before copying an expression between systems, identify the scheduler’s dialect and read its schedule and timezone rules.
Checklist by scenario
Run a task every day at a specific time
For a traditional five-field cron schedule, 30 2 * * * means 02:30 every day in the scheduler’s configured timezone. Confirm that 02:30 is the intended local or UTC time, then verify the command’s path, permissions, environment variables, and log destination.
- Write the intended timezone beside the schedule.
- Use absolute paths where the scheduler may have a smaller environment than your shell.
- Log both the start time and the result, including failures.
- Run the command manually as the same user before enabling the schedule.
Run every few minutes or hours
Use an interval only after deciding whether you mean fixed clock boundaries or elapsed time. */10 * * * * generally targets minute 0, 10, 20, and so on. It does not necessarily mean “ten minutes after the previous run finishes.” If a job can run longer than its interval, add concurrency protection or design the task to be safely repeatable.
Run on weekdays, month-start, or month-end
A weekday schedule such as 0 9 * * 1-5 is easy to read, but confirm how the platform numbers Sunday and whether names such as MON are accepted. Month-end schedules need extra care because months have different lengths. A rule for day 31 will not run in shorter months. For reliable month-end processing, schedule a daily check that determines whether the current date is the final day, or use a scheduler feature specifically designed for calendar conditions.
Use Kubernetes CronJobs
Start with the Kubernetes version and documentation used by your cluster. Confirm the supported schedule syntax, timezone configuration, concurrency policy, missed-run behavior, history limits, and deadline settings. A Kubernetes CronJob creates Jobs; it does not automatically guarantee that only one task instance will ever be active. Make the application idempotent and inspect the resulting Jobs and Pods when diagnosing a problem.
Use CI or a cloud scheduler
Check whether the platform evaluates schedules in UTC or lets you select a timezone. Also verify whether the schedule is paused, restricted to a default branch, affected by repository or account settings, or subject to platform-specific delivery behavior. Treat the scheduler as a trigger rather than proof that the work completed: the workflow should expose success, failure, retries, and partial completion.
What to double-check
Timezone and daylight-saving behavior
“02:00 every day” is incomplete unless it includes a timezone. Record the timezone in the job description, deployment configuration, and runbook. If the scheduler uses UTC, convert the desired local time deliberately rather than guessing. If it uses a regional timezone, determine what happens when clocks move forward or backward. A local time may be skipped, occur twice, or shift relative to UTC. For billing, reporting, and other sensitive processes, consider UTC or implement explicit business-calendar logic.
Day-of-month and day-of-week semantics
Some cron implementations treat day-of-month and day-of-week as an OR condition when both are restricted; other schedulers may document different behavior. Do not assume that 0 8 1 * MON means only Mondays that fall on the first day of the month. Test the expression in the actual scheduler or replace the expression with a clearer application-level condition.
Execution and delivery assumptions
- Can two instances overlap?
- What happens if the scheduler, node, or service is unavailable at the intended time?
- Are missed runs skipped, delayed, or replayed?
- Does a retry create duplicate side effects?
- Where can an operator see the scheduled event, job, container, and application logs?
For a practical test, use a near-future schedule in a non-production environment, record the expected next run, and compare it with the scheduler’s displayed next-run time. A cron expression tester or cron expression builder can help inspect dates, but the production platform remains the final authority.
Common mistakes
- Using six fields in a five-field scheduler. Some systems add seconds; traditional cron usually does not. Count the fields and check the platform format.
- Forgetting the timezone. A correct expression can still run at the wrong business hour when environments use different defaults.
- Assuming a command has your interactive shell environment. Set required paths, configuration, and credentials explicitly. Keep secrets in the platform’s secret store rather than placing them in the expression.
- Scheduling without concurrency control. A slow or retried job can overlap with the next invocation. Use a lock, queue, concurrency policy, or idempotent processing design.
- Testing only the expression. A valid schedule does not prove that the command can authenticate, reach its dependencies, write output, or handle partial failure.
- Copying syntax between platforms. A schedule that works in Linux cron may need a different timezone declaration, wrapper, or field format in Kubernetes, CI, or a cloud scheduler.
For broader operational diagnosis, pair schedule logs with an API debugging workflow and a local-to-cloud debugging checklist. If the job depends on configuration, review how environment variables and secrets differ across local, staging, and production environments.
When to revisit
Revisit a cron schedule before seasonal planning cycles, timezone-sensitive reporting periods, daylight-saving transitions, or any migration between servers, containers, CI systems, and cloud providers. Also review it whenever the command, container image, identity, dependency, data window, or retry policy changes.
Keep a small schedule record with the expression, plain-language meaning, timezone, owner, expected runtime, concurrency policy, failure alert, and last test date. Twice a year, or whenever a platform changes its scheduling behavior, test representative expressions again. Include a weekday job, a month-boundary job, an interval job, and at least one timezone-sensitive job if those patterns exist in your environment.
Before publishing or deploying a new schedule, complete this final sequence:
- Write the desired recurrence in plain language.
- Identify the scheduler dialect and timezone.
- Build the expression and inspect upcoming run times.
- Test the command under the scheduler’s identity and environment.
- Define overlap, retry, missed-run, and duplicate-work behavior.
- Deploy a non-production test and verify logs and alerts.
- Document the owner and set a reminder to review the schedule when workflows or tools change.
For a collection of quick tools for programmers, including cron utilities alongside JSON, SQL, JWT, and encoding helpers, see the comparison of free online developer utilities. When the scheduled task calls an API, the API debugging workflow can help separate a scheduling problem from an application or HTTP problem.