TechCompare LogoTechCompare

Cron timezone issues: why your job runs at the wrong time and how to fix it

Always set CRON_TZ in your crontab if you care about local time. Prefer UTC for server jobs and document that decision. For DST safety, either accept the skip/double behavior (which is usually harmless for idempotent jobs) or switch to systemd timers with a monotonic calendar event.

Cron evaluates schedules against the system's local timezone, not UTC. This causes two classes of bugs: the server is set to UTC but you wrote the schedule in your local time, or the server is in a DST-observing timezone and your job skips or duplicates when the clocks change. Both are frustrating and both are preventable.

By TechCompare · Updated

Schedule pattern
Cron timezone pitfalls
timezone
Category
Pitfalls
Common cron mistakes and fixes

How this is calculated

On a UTC server, a 0 2 * * * job runs at 2 AM UTC. If you're in US Eastern time and thought '2 AM my time,' the job actually fires at 10 PM Eastern (or 9 PM depending on DST). The fix is to either set CRON_TZ=America/New_York in your crontab or adjust the hours: 0 7 * * * for 2 AM Eastern in standard time, 0 6 * * * during DST. For DST spring-forward, cron skips the hour that doesn't exist. For fall-back, cron runs the job twice for the repeated hour (typically at the first occurrence). If your job is idempotent this is fine. If not, add a guard.

Verdict

Two failure modes hide in timezone handling, and CRON_TZ is the clean fix for both. On a UTC box, 0 2 * * * fires at 2 AM UTC, not your local 2 AM, so shift to 0 7 for Eastern standard or 0 6 during DST. Spring-forward skips the missing hour and fall-back runs the job twice, which is harmless for idempotent tasks but breaks stateful ones.

More Cron scenarios

Frequently asked questions

Does cron use UTC or local time?
Local system time, by default. Cron evaluates your schedule against whatever timezone the server is set to, which on cloud VMs and containers is usually UTC. A job you wrote thinking about your own timezone will fire hours off if the server disagrees. Check with timedatectl or date before assuming.
How do I make a cron job run in a specific timezone?
Set CRON_TZ at the top of the crontab: CRON_TZ=America/New_York followed by your schedules makes them evaluate against Eastern time regardless of the server's configured zone. Not every cron daemon supports CRON_TZ, so the portable fallback is running the server in UTC and converting your hour fields by hand.
What happens to cron jobs during daylight saving time changes?
Spring-forward skips the hour that doesn't exist, so a 2:30 AM job never runs that night. Fall-back repeats an hour and the job typically fires twice. Idempotent jobs shrug this off. Stateful jobs that double-charge a customer or double-send an email need a guard, like a marker file the script checks before doing work.