A reliable cron schedule starts with more than memorizing five fields. This guide explains Linux crontab syntax, shows copy-ready cron schedule examples, compares Linux and Quartz expressions, and provides a practical checklist for building and testing recurring jobs before they reach production.
Overview
Cron is a scheduler for recurring tasks such as database backups, temporary-file cleanup, report generation, certificate checks, and application maintenance. A cron expression describes when a command should run; the command itself still needs correct paths, permissions, environment variables, logging, and error handling.
The familiar Linux crontab format has five time fields followed by a command:
minute hour day-of-month month day-of-week command
| Field | Typical values | Meaning |
|---|---|---|
| Minute | 0–59 | Minute within the hour |
| Hour | 0–23 | Hour in the scheduler's timezone |
| Day of month | 1–31 | Calendar day |
| Month | 1–12 or names in some implementations | Month of the year |
| Day of week | 0–7 or names in some implementations | Weekday; 0 and 7 commonly represent Sunday |
The most useful special characters are * for every permitted value, , for a list, - for a range, and / for a step. For example, 0,30 means at minute zero and thirty, 1-5 means a range, and */15 means every fifteen units within that field.
Use an online cron expression builder or test cron expression online tool as a readable first check, but confirm the result against the scheduler that will actually run it. Online developer tools may use a particular cron dialect, and a schedule that looks valid in one format can be rejected or interpreted differently in another.
Checklist by scenario
Every day at a fixed time
To run a command at 02:15 every day, use:
15 2 * * * /usr/local/bin/backup.sh
Use an absolute path to the script and, where practical, an absolute path to its interpreter or executable. Cron often runs with a smaller environment than an interactive shell.
Weekday reports
This expression runs at 08:00 on weekdays in the common Linux format:
0 8 * * 1-5 /usr/local/bin/generate-report
Confirm how your scheduler represents Sunday and whether it accepts weekday names before using named values. If the report must avoid a local holiday, cron alone may not be enough; use an application-level calendar check or a scheduler with calendar support.
Recurring cleanup jobs
To run cleanup every fifteen minutes:
*/15 * * * * /usr/local/bin/cleanup-temp
For a job that should run only during a maintenance window, constrain the hour field as well:
*/15 1-4 * * * /usr/local/bin/cleanup-temp
Make the cleanup command safe to repeat. It should limit what it deletes, handle missing files, and produce a useful log.
Weekly backups
For a Sunday backup at 03:30, a common Linux expression is:
30 3 * * 0 /usr/local/bin/weekly-backup
Decide whether the command should overlap with a previous run. If backups can take longer than expected, add a lock or another concurrency control so two copies do not operate on the same data.
Monthly maintenance
To run on the first day of each month at 04:00:
0 4 1 * * /usr/local/bin/monthly-maintenance
A schedule for the last calendar day of a month is not portable across basic five-field cron implementations. It is usually safer to run daily and let the script determine whether today is the final day, or use a scheduler that explicitly supports a last-day modifier.
Intervals and human schedules
Translate the requirement before writing fields. “Every twenty minutes” is different from “at 20 minutes past every hour,” and “at 09:00 local time” is different from “every nine hours.” Write down the intended timezone, allowed days, expected runtime, and whether missed executions should be replayed.
For a schedule that must follow business time through daylight-saving changes, consider a timezone-aware hosted scheduler, system timer, or application scheduler. Basic cron behavior around skipped and repeated local times varies, so do not assume that a daylight-saving-sensitive job will run exactly once without testing.
Linux cron versus Quartz
Linux crontab normally uses five time fields. Quartz commonly uses six or seven fields, adding seconds at the beginning and, optionally, a year field:
second minute hour day-of-month month day-of-week [year]
Quartz also supports modifiers such as ?, L, and # in contexts where ordinary Linux cron does not. Do not paste a Quartz expression directly into a Linux crontab. Likewise, hosted schedulers may add their own timezone settings, retry behavior, minimum interval, or restrictions on command execution. Read the target scheduler's expression rules before deployment.
What to double-check
- Dialect: Identify whether the target is Linux cron, a container platform, a CI system, Quartz, or a hosted scheduler. Check field count, supported modifiers, and timezone syntax.
- Timezone: Establish whether the scheduler uses the server timezone, UTC, a per-job setting, or an account-wide setting. Record the choice beside the schedule.
- Day fields: When both day-of-month and day-of-week contain restrictions, implementations may use an OR-style interpretation rather than requiring both conditions. Test this case instead of relying on intuition.
- Environment: Set required
PATH, working directory, locale, credentials, and configuration explicitly. Review the secure handling of secrets using the guidance in our environment variables and .env files checklist. - Permissions: Confirm that the scheduler's user can execute the script, read its inputs, write its output, and access any required network or database resource.
- Output and alerts: Redirect output to a controlled log or an approved notification mechanism. Make failures visible without exposing tokens, passwords, or personal data.
- Concurrency: Check the expected runtime and decide what happens if the next trigger arrives before the previous run ends.
- Recovery: Decide whether a missed run should be skipped, retried, or caught up. Traditional cron generally triggers based on the clock; it is not automatically a durable job queue.
Before installing a schedule, use a cron expression builder to inspect the next several run times. Then test the complete command in the same account and environment that will run it. A parser can validate syntax, but only an end-to-end test can reveal missing permissions, paths, credentials, or network access.
Common mistakes
Confusing fields. In 0 2 * * *, the first value is the minute and the second is the hour. Saying “2:00” does not mean placing 2 in the first field.
Using a six-field expression in five-field cron. An expression beginning with seconds may be valid in Quartz but invalid in a standard Linux crontab.
Assuming shell behavior. Aliases, interactive startup files, relative paths, and a familiar working directory may not exist. Use a wrapper script with explicit settings when the command has more than a simple argument list.
Ignoring special characters. Percent signs can have special meaning in some crontab implementations, and shell metacharacters can change how arguments are interpreted. Quote and escape deliberately, then test the exact installed entry.
Testing only the expression. A green result in an online tester does not prove that the job can run successfully. Validate the command, its exit status, its logs, and its effects.
Scheduling at a risky time. A job at the top of the hour may coincide with other maintenance tasks. Stagger noncritical work where possible and document dependencies.
For broader automation work, a repeatable API or deployment workflow can be easier to audit than ad hoc commands. Related developer utilities such as API testing tools and status-code checkers can help verify the services that scheduled jobs call.
When to revisit
Revisit a cron schedule before seasonal planning cycles, timezone changes, infrastructure migrations, application releases, or changes to backup and retention requirements. Review it whenever the command moves hosts, containers, users, directories, or credential stores. Also reassess schedules after changing from Linux cron to Quartz or a hosted scheduler, because field syntax and execution guarantees may change.
At least twice a year, audit the schedule inventory: owner, purpose, expression, timezone, command path, expected duration, log location, alert destination, and recovery plan. Check the next-run times around daylight-saving transitions and month boundaries. Remove abandoned entries and update comments when a business requirement changes.
Before you deploy a new expression, follow this short action list:
- Write the schedule in plain language, including timezone and missed-run behavior.
- Choose the target scheduler and confirm its dialect.
- Build the expression with a trusted parser or online cron expression builder.
- Inspect several upcoming run times, including a boundary such as midnight or month-end.
- Run the command manually as the scheduler user in a controlled environment.
- Deploy with logging, failure visibility, and concurrency protection.
- Record an owner and a review date so the job remains understandable.
This workflow makes cron useful as a dependable developer productivity tool rather than a mysterious line of punctuation. When you need to validate other structured inputs in the same process, consult our guides to online formatters and encoders and JSON Schema validators.