Cron schedules look simple until a job runs at the wrong time, runs twice, or never runs at all. This guide is designed as a reusable reference for developers, platform engineers, and IT admins who need to create or review recurring jobs with confidence. It explains how cron expressions are structured, where implementations differ, which timezone and daylight saving edge cases matter, and what to validate before shipping an automation into production.
Overview
This article gives you a practical cron expression guide you can return to whenever you create, review, or debug scheduled tasks. Rather than treating cron as a memorization exercise, it focuses on the decisions that matter in real environments: what syntax your scheduler actually supports, what local time means for the job, how often the task can safely run, and what checks reduce surprises.
At a high level, a cron expression defines when a command or job should run. The classic Unix form uses five fields:
- Minute
- Hour
- Day of month
- Month
- Day of week
A familiar example is 0 2 * * *, which usually means “run at 02:00 every day.” In many cloud and application schedulers, though, the syntax may include a sixth field for seconds, a seventh field for year, or special characters not supported by traditional cron. That is why the first rule of cron is simple: validate against the exact scheduler you use.
Common field patterns include:
*for “every value”,for a list, such as1,15,30-for a range, such as1-5/for a step, such as*/10
Some schedulers also support special symbols like ?, L, W, or #. These can be useful, but they are also a common source of portability problems. If a schedule must work across tools, prefer the simplest supported syntax.
It also helps to separate two concerns that are often mixed together:
- The schedule: when the system will attempt to start the job
- The job behavior: what happens if a previous run is still executing, if the host is down, or if the task fails
A correct cron expression does not guarantee a reliable automation. If the task is business-critical, pair schedule design with logging, monitoring, retries, and run overlap controls. Teams working on broader reliability practices may also want to connect job expectations to service objectives and alerting. For related operational guidance, see SRE Service Level Objectives Guide: How to Define SLIs, SLOs, and Error Budgets and Prometheus Alerting Rules Checklist for Kubernetes and Cloud Workloads.
Quick cron examples
*/5 * * * *— every 5 minutes0 * * * *— at the top of every hour30 9 * * 1-5— 09:30 on weekdays0 0 1 * *— midnight on the first day of every month15 3 * * 0— 03:15 every Sunday in implementations where 0 maps to Sunday
If you also work with structured payloads, config templates, or expression-heavy automation, it is worth keeping adjacent tools nearby. For example, malformed schedule configuration often sits next to malformed JSON, and validation is faster when you can confirm both quickly. See JSON Formatter and Validator Guide: Fixing Common Parse Errors Fast and Regex Tester Guide: Common Patterns Developers Reuse and How to Validate Them for related workflow utilities.
Checklist by scenario
Use this section as a pre-deployment checklist. Start with the scenario that matches your job, then adapt it to your scheduler.
1. Every few minutes jobs
Examples: cache refreshes, polling tasks, status syncs, queue cleanup, low-risk housekeeping.
- Use a simple step expression such as
*/5 * * * *or*/15 * * * *. - Confirm whether the scheduler anchors the step at minute 0 or interprets it differently.
- Make sure the job is safe to run repeatedly and tolerate duplicate execution if needed.
- Check the average run duration. A 5-minute schedule for a job that often takes 8 minutes creates overlap risk.
- Set timeouts so a stalled run does not pile up behind the next trigger.
- Prefer idempotent job logic, especially for syncs and cleanup.
2. Daily jobs
Examples: backups, reports, billing preparation, batch imports, retention tasks.
- Choose a low-contention hour rather than defaulting to midnight.
- Decide whether “daily” means UTC daily or local-business-time daily.
- Document the intended timezone in the job definition or repository.
- Check how daylight saving changes affect the target hour.
- If the job touches databases or APIs, verify downstream maintenance windows.
- Make sure logs include the scheduled timestamp and actual start time.
Example: 0 2 * * * is clear syntactically, but operationally it raises questions. Is 02:00 local time? UTC? What should happen on days when 02:00 is skipped or repeated due to DST? Those answers belong in the job documentation, not just in team memory.
3. Weekday business-hour jobs
Examples: work queue processing during staffed hours, report generation, internal notifications, office-hours maintenance.
- Use a weekday expression such as
0 9-17 * * 1-5if supported by your scheduler. - Confirm which numeric values represent weekdays and whether both 0 and 7 can mean Sunday.
- Check whether local holidays matter. Cron cannot express “weekdays except holidays” on its own.
- If the business spans regions, avoid assuming one office timezone fits all users.
- For customer-facing actions, verify that “business hours” aligns with the service expectation.
4. Monthly or calendar-sensitive jobs
Examples: invoice generation, monthly exports, quota resets, compliance checks.
- Review whether the job should run on the first day, last day, or a specific weekday of the month.
- Be careful with dates like the 29th, 30th, or 31st. Some months do not have them.
- If the business rule is “last business day,” do not assume cron alone can express it cleanly.
- Add explicit handling for months with fewer days.
- Test end-of-month behavior across multiple months, not just the current one.
Example: 0 0 31 * * will not run in months without a 31st day. That may be correct, or it may hide a business bug.
5. Weekly maintenance jobs
Examples: index optimization, artifact cleanup, rotating non-sensitive data, non-urgent resource maintenance.
- Confirm the day-of-week mapping for your scheduler.
- Avoid stacking many heavy jobs at the same time, such as Sunday at 00:00.
- Check cluster, database, and backup windows before choosing a time.
- Make sure the job can be safely skipped or manually re-run if maintenance overlaps occur.
6. Kubernetes CronJobs
Examples: cluster tasks, data compaction, scheduled reconciliation, recurring platform jobs.
- Validate the cron expression in the context of Kubernetes CronJob behavior, not just generic cron syntax.
- Review concurrency policy so old runs do not overlap with new ones.
- Set starting deadline behavior thoughtfully if missed runs matter.
- Use resource requests and limits appropriate for the workload.
- Send logs to your standard observability pipeline so failures are easy to inspect.
- Make sure secrets, config, and image tags are versioned and auditable.
If the scheduled task affects cluster resource usage, revisit broader platform efficiency too. A recurring job can become a hidden cost multiplier when it scales poorly. Related reading: Kubernetes Cost Optimization Checklist for Teams Running Production Clusters.
7. CI/CD scheduled pipelines
Examples: nightly builds, dependency updates, scheduled scans, environment refreshes, test suites.
- Confirm whether your CI/CD platform uses standard cron or a variant.
- Document whether the schedule uses repository timezone, project timezone, or UTC.
- Check branch targeting. Scheduled jobs often run against a default branch unless configured otherwise.
- Make the pipeline output clearly identify that it was schedule-triggered.
- Ensure long-running test suites do not collide with normal deployment workflows.
For broader platform tradeoffs, see GitHub Actions vs GitLab CI vs Jenkins: Feature Comparison and Maintenance Tradeoffs and CI/CD Pipeline Bottleneck Finder: Where Builds and Deployments Usually Slow Down.
8. Security and token rotation jobs
Examples: key rotation reminders, certificate checks, secret syncs, token cleanup.
- Do not rely on an ambiguous local timezone for security-sensitive deadlines.
- Make sure the job failure path alerts the right team.
- Review permissions carefully; scheduled jobs often accumulate excessive access.
- Store sensitive values in a proper secrets system rather than inline configuration.
Useful companion references: Secrets Management Comparison: Vault vs AWS Secrets Manager vs Doppler vs 1Password and JWT Debugging Guide: How to Inspect Claims, Expiry, Signatures, and Common Errors.
What to double-check
This is the core cron validation checklist. Before approving a schedule, answer these questions explicitly.
1. Which cron dialect are you using?
Not every scheduler implements the same syntax. Some use five fields, some six, some seven. Some support named weekdays and months. Others support Quartz-style symbols, while traditional cron does not. A cron schedule tester is only useful if it matches your runtime environment.
2. What timezone is authoritative?
Timezone issues are one of the most common sources of scheduling confusion. Decide whether the schedule should follow:
- UTC for consistency across environments
- A server timezone inherited from the host
- An application-configured timezone
- A business timezone tied to a region or team
Write that decision down next to the expression. If the job matters, include it in code comments, documentation, or job metadata.
3. What happens during daylight saving transitions?
Two edge cases matter:
- Skipped time: a local hour may not exist when clocks move forward.
- Repeated time: a local hour may occur twice when clocks move back.
If your job is scheduled in the affected window, decide whether a skipped run is acceptable and whether duplicate runs are safe. If that risk is not acceptable, UTC scheduling may be simpler.
4. Can the job overlap with itself?
A schedule such as every 5 minutes is harmless only if the job usually completes in under 5 minutes or if overlap is controlled. Check concurrency settings, locking strategy, and idempotency. This matters especially for data updates, external API calls, and billing-related tasks.
5. What happens if a run is missed?
Consider host restarts, controller outages, deployment windows, and paused environments. Ask:
- Should missed runs be ignored?
- Should one missed run be caught up?
- Should all missed runs be replayed?
The right answer depends on the task. A report generation job may tolerate a missed run. A ledger reconciliation task may not.
6. Is the schedule readable to the next person?
Even a correct expression can be hard to review. Add a plain-language explanation such as “Runs at 09:30 Europe/London on weekdays.” If the expression is generated or embedded in YAML, ensure formatting does not obscure meaning. For adjacent configuration hygiene, the Terraform Best Practices Checklist: State, Modules, Drift, and Security offers useful habits for documenting operational intent near infrastructure definitions.
7. Are alerting and observability in place?
A schedule without visibility becomes a silent failure mode. At minimum, capture:
- last successful run time
- last failed run time
- duration
- exit status
- logs tied to a unique run identifier
For high-value tasks, add alerts for consecutive failures or stale runs rather than only for hard errors.
8. Have you tested future dates, not just syntax?
Syntax validation is not enough. Inspect upcoming fire times across edge periods such as month boundaries, DST changes, and weekends. This is where a cron schedule tester is most useful: not just to parse an expression, but to preview the next several scheduled executions under the intended timezone.
Common mistakes
The fastest way to improve cron reliability is to avoid a few recurring errors.
Assuming all cron implementations behave the same
This is the root mistake behind many production incidents. If your team moves between Linux cron, cloud schedulers, CI platforms, and Kubernetes CronJobs, syntax portability should never be assumed.
Using local server time without meaning to
A job may work in development and drift in production simply because the host timezone changed, the container image differs, or the scheduler defaults to UTC. Make timezone an explicit design choice.
Scheduling at midnight by default
Midnight is a crowded time. Backups, retention tasks, daily reports, billing resets, and log rotations often pile up there. Spread load deliberately.
Ignoring month-length and weekday semantics
Expressions involving the 29th, 30th, 31st, or specific weekdays of the month deserve extra review. If the business rule is more nuanced than the expression, encode the nuance in job logic rather than pretending cron can express it all.
Not planning for duplicate or missed execution
Even with a correct schedule, infrastructure events happen. Design jobs so duplicates are harmless where possible, and define how missed runs should be handled.
Leaving no human-readable description
17 4 1 * * is concise, but it is not self-explanatory. Add a short note. Future-you will need it.
Testing only the happy path
If you only test that an expression parses, you miss the operational edge cases. Good cron validation includes future execution previews, timezone review, and a runbook for failures.
When to revisit
Cron schedules are not set-and-forget configuration. Revisit them whenever the assumptions behind the schedule change. A short review at the right time is usually cheaper than debugging a missed or duplicated job later.
Revisit before seasonal planning cycles
- Check schedules tied to local time before daylight saving changes.
- Review end-of-month and end-of-year jobs before finance or reporting deadlines.
- Confirm holiday-period expectations for weekday-only jobs.
Revisit when workflows or tools change
- You move jobs from one CI/CD platform to another.
- You shift from host cron to Kubernetes CronJobs or a managed scheduler.
- You standardize on UTC or change region-specific operations.
- You add new retry, locking, or observability standards.
Practical action checklist
- List every scheduled job and its owner.
- Record the exact cron expression, scheduler type, and authoritative timezone.
- Write a one-line plain-English description for each schedule.
- Preview future run times in a cron schedule tester that matches your runtime.
- Check DST windows, month boundaries, and overlap risk.
- Verify logging, failure alerts, and missed-run behavior.
- Review whether the job should remain on cron at all or move to an event-driven trigger.
If you treat cron as part of developer workflow quality instead of background plumbing, teams spend less time chasing avoidable surprises. Keep this page as a standing review checklist for any recurring automation, and update your schedules whenever the business timezone, platform, or job criticality changes.