SameOS ~/tools/cron-scheduling.md

Avoiding Common cron Schedule Mistakes

cron (the Linux scheduler that runs jobs automatically at set times) reads a crontab expression of five fields: minute, hour, day of month, month, and weekday. The syntax is short but easy to get wrong, and jobs quietly running on the wrong schedule for months are common. Here are the mistakes that come up most often.

Frequent Mistakes

The most common one is writing * * * * * while meaning "every hour on the hour" - that expression runs every minute. The hourly version is 0 * * * *. Second, */30 means "every 30 minutes," not "once after 30 minutes." Third, in the weekday field both 0 and 7 mean Sunday.

When you restrict both the day-of-month and weekday fields, the two conditions combine with OR, not AND. For example, 0 3 1 * 1 does not mean "the 1st when it falls on a Monday"; it runs at 3 AM on the 1st of every month and on every Monday. This is long-standing standard cron behavior, so it is safest to verify with a tool first.

Safe Rules on a Small Server

Schedule heavy jobs such as backups, thumbnail cleanup, and log compression during quiet hours and keep them from overlapping. Piling several jobs on the same moment (like 0 0 * * *) spikes disk and CPU together; simply scattering the minute values (3, 17, 42) smooths the load. For jobs that may run longer than their interval, add a duplicate-run guard such as flock.

The crontab explainer tool page describes each field and shows the next three run times in your browser timezone. Use it to confirm the schedule matches your intent before deploying.

Preventing Overlap: crontab With flock

Long jobs like collectors corrupt data when the next run starts before the last finishes. One flock line prevents it.

# 1) open the crontab editor
crontab -e

# 2) add this one line — flock blocks overlap
#    (if the previous run is still going, this run is skipped)
0 * * * * /usr/bin/flock -n /tmp/collect.lock /usr/bin/php /home/me/collector.php
#    runs at the top of every hour. -n in flock -n = "skip, do not wait"

# 3) common mistake — cron has a different PATH than your login shell,
#    so bare "php" may not be found. Always use an absolute path.
#    find it:  which php

# 4) keep a log of runs (so you can diagnose failures)
0 * * * * flock -n /tmp/c.lock php /home/me/collector.php >> /home/me/cron.log 2>&1
Open the crontab explainer Read the automation lessons