Cron job

BackendTier 2 · build and shipPhase 4 · Take money

Work scheduled to run on a clock rather than in response to a user: nightly reports, daily settlements, weekly cleanups.

Some work is not triggered by a user at all but by the clock: nightly reports, daily cleanup, a 9am reminder. Someone running these by hand is unreliable and does not scale. A cron job exists to run a task automatically on a schedule, so recurring work happens on time without anyone remembering to start it.

Some tasks aren't triggered by users at all; they run on a timetable. A cron job is a scheduled task: "every night at 2am, generate yesterday's sales report," "every hour, expire abandoned carts."

They quietly keep the system tidy and produce regular outputs. When a scheduled report is missing or wrong, a cron job is usually involved.

A junior PM, stuck

The daily sales report did not land in my inbox this morning when I expected it overnight. When I asked the dev he pasted "0 2 * * *" and asked whether I meant 2am UTC or 2am Dhaka time. The expression means nothing to me, so I cannot answer him or tell whether the report is actually broken.

That string is a schedule, and the whole confusion is one timezone line above it, so this is a five minute read. Below is the crontab with the three TiffinBox jobs and the timezone the file runs in. Once you can read the fields you will see the report is not missing, it is just firing on a different clock than you pictured.

TiffinBox crontab, as the server runs it
crontab
# TZ=UTC (Dhaka is UTC+6)
# fields: minute hour day-of-month month day-of-week command
0 2 * * * node jobs/sales-report.js
0 * * * * node jobs/expire-carts.js
30 1 * * * node jobs/payment-reconcile.js

Click a step to see the lines it points at.

Reading a cron expression as local time. "0 2 * * *" is 2am only if the crontab runs in your timezone; here it runs in UTC, so it is 8am Dhaka. Always find the TZ line first.
Filing "the nightly report is broken" before checking when it was actually scheduled to run. It may have fired exactly on time, just on a clock six hours off from the one you assumed.
Assuming "nightly" in a ticket means overnight for the reader. Nightly is whatever the job's timezone says; name the timezone when you ask for a schedule change.
Requesting a new schedule as "run it at 2am" without saying whose 2am. The dev will set it in the server's timezone; say "2am Dhaka" or give the UTC time so it lands when you expect.

Tell the dev: "That's 2am UTC, and the crontab runs in UTC, so the report actually fires at 8am Dhaka, right into the breakfast rush. It isn't broken, it's just on the UTC clock. Can we move it to 20:00 UTC so it arrives around 2am Dhaka, before the workday?" You read a cron line, applied the timezone in the header, and turned a "missing report" into a scheduling fix.

"The daily report didn't arrive" often means a cron job failed; knowing they exist tells you where to point.
Timing and time zones matter: a nightly job's "night" depends on which time zone it runs in, a common source of confusion.

"The reconciliation cron failed last night, that's why the numbers are off."

Appears in Phase 4, Take money.