An asterisk means "any value"
30 * * * * only constrains the minute, so it runs at :30 of every hour. It does not mean "hourly" — it means you only set a minute condition.
브라우저 내부 처리
Cron syntax takes five minutes to learn. The hard part is a schedule that is syntactically correct and still does not run when you expect. These are the failure points in the order you tend to hit them.
Minute, hour, day of month, month, day of week. Rather than memorising the order, it helps to understand that each field is not "when" but "which values match". Cron wakes up every minute, checks whether the current time satisfies all five fields, and runs the job if it does.
30 * * * * only constrains the minute, so it runs at :30 of every hour. It does not mean "hourly" — it means you only set a minute condition.
*/15 matches minutes divisible by 15, so 0, 15, 30 and 45. 7 */3 * * * is not "every three hours from now" but 00:07, 03:07, 06:07 and so on.
0 9-18/2 * * 1-5 means weekdays, on the hour, every two hours from 09:00 to 18:00. Commas list individual values, as in 0 0,12 * * *.
That is the syntax. Everything below is where real incidents come from. Paste an expression into the cron expression parser as you read to see the upcoming run times.
This is the most common cron mistake, and because it is not a syntax error the job simply runs on a different schedule than you expected.
When both the day-of-month and day-of-week fields are set to something other than *, most cron implementations combine them with OR. So 0 0 1 * 1 is not "the 1st, when it is a Monday" but "the 1st or any Monday". A job you expected to run monthly runs about five times a month.
It is the intended behaviour of Vixie cron and it is specified in POSIX. The purpose was to express two schedules on one line, such as "back up on the 1st and every Friday". The problem today is that most people expect AND without knowing this rule.
Keep one of the two fields as *. Use 0 0 1 * * for monthly and 0 0 * * 1 for weekly. If you genuinely need AND, schedule broadly in cron and exit early in the script after checking the date. A condition in your own code is safer than relying on scheduler-specific behaviour.
Vixie cron and cronie use OR. Quartz and some cloud schedulers use a different syntax entirely, requiring ? in one of the two fields and forbidding both at once. So when moving an expression to another runtime, verify it against that runtime's documentation instead of copying the string.
Most official Linux images start in UTC. If you write 0 9 * * * meaning "9am", it fires at 18:00 Korean time. A schedule that was correct locally slips by nine hours after deployment.
Run date inside that environment. Support for TZ= or CRON_TZ= in the crontab varies by implementation, and where it exists it often applies only to lines after the declaration.
Korea has no daylight saving, but in US or EU regions a given wall-clock time can be skipped or repeated on transition days. That is why scheduling between 02:00 and 03:00 is usually avoided.
Verify the intended times with the upcoming-run list in the cron expression parser, and use the Unix timestamp converter when you need to line up epoch values with local time.
Three ways a correct schedule still breaks in production, most often on jobs whose runtime approaches their interval.
Cron does not check whether the previous process is still alive. A job scheduled */5 that starts taking seven minutes will pile up until connections or memory run out. Take a lock with flock -n, or check a PID file and exit if the job is already running. Skipping is usually safer than retrying.
Scaling a container that ships the same crontab to three replicas runs the job three times: three notifications, three settlement writes. Put the scheduler somewhere independent of replica count — a single dedicated worker or a managed scheduler — or make the job idempotent.
Cron tries to mail stdout and stderr, and on a server without mail configured that output simply disappears. Without >> /var/log/job.log 2>&1 you have no way to see a failure. Better still, emit a heartbeat at the end of the job and alert when it stops arriving — a job that never ran is far harder to notice than one that errored.
Cron runs with a minimal environment, which is why a command that works in your terminal reports "command not found" under cron. Use absolute paths or load the environment explicitly at the top of the script. Python virtual environments are a frequent offender.
*. If both are set, the schedule is an OR.date in the deployment environment to confirm the time zone.Next: verify expressions with the cron expression parser, read epoch values from logs with the Unix timestamp converter, and line up intervals and settlement dates with the date calculator.