Cron expression for every Monday
The cron expression 0 0 * * 1
runs at 12:00 AM, only on Monday. The restricted fields are minute 0, hour 0, and day of week 1; the remaining asterisks match anything. That works out to one run per week.
0 0 * * 1 Field breakdown
| Field | Value | Meaning |
|---|---|---|
| Minute | 0 | The top of the hour (:00) |
| Hour | 0 | 00:00 (midnight) |
| Day of month | * | Every day of the month (1–31) |
| Month | * | Every month (1–12) |
| Day of week | 1 | Monday |
Next runs
- —
- —
- —
- —
- —
Run times are calculated in your browser timezone. The scheduler that executes the job uses its own — always UTC on Vercel Cron, UTC by default on GitHub Actions, the host clock on crontab.
How this schedule works
Cron evaluates the five fields of 0 0 * * 1 — minute, hour, day of month, month, day of week — against the clock once a minute and starts the job on any minute where all five match, which cronstrue reads as "At 12:00 AM, only on Monday": one run per week. The day-of-week field is numbered 0 to 6 with Sunday at 0, so 1 selects Monday. Day of month is left as an asterisk, so the calendar date is unrestricted and only the weekday decides.
When to use every monday
Monday at 00:00 is where weekly work naturally lands: reports that summarize the week just ended, counters and quotas that reset with the working week, a data refresh that should be finished before anyone logs in. Running in Monday's first minute means the previous week is closed and complete, which keeps the date arithmetic inside the job simple. If the output is for people rather than systems, consider 09:00 instead, so that a failure still has most of Monday left in which to be noticed and fixed.
Common mistakes with every monday
Two mistakes cluster around the day-of-week field. The first is the numbering: cron counts Sunday as 0, so Monday is 1, while ISO 8601 counts Monday as day 1 of 7 — and people reaching for 0 by analogy schedule the job on Sunday. The second is combining day of week with a day-of-month value. When both day fields are restricted, cron fires when either matches, not both, so 0 0 1 * 1 runs on every Monday and on the 1st of the month: five or six runs a month rather than the one that was intended.
Platform snippets
The same expression, ready to paste into the four schedulers that read five-field cron. The notes below each snippet are the ones that follow from this schedule; the cron expression generator lists every caveat for every platform.
GitHub Actions
name: Scheduled workflow
on:
schedule:
- cron: '0 0 * * 1'
workflow_dispatch:
jobs:
scheduled:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run job
run: echo "Running scheduled job" - • Workflows scheduled at the top of the hour may be delayed during high-load periods. Consider offsetting the minute field (e.g. "5 0 * * 1") for more reliable timing.
Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: my-cron-job
spec:
schedule: "0 0 * * 1"
jobTemplate:
spec:
template:
spec:
containers:
- name: job
image: my-image:latest
command: ["/bin/sh", "-c", "echo Running"]
restartPolicy: OnFailure - • Do NOT use CRON_TZ or TZ inside the schedule string. Kubernetes 1.29+ rejects this at creation with a validation error; earlier versions issue a warning. Existing CronJobs using TZ/CRON_TZ will continue to warn on update. Use the timeZone field instead.
Vercel Cron
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"crons": [
{
"path": "/api/cron",
"schedule": "0 0 * * 1"
}
]
} - • Hobby plan: invocations occur within the specified hour (e.g. "0 8 * * *" runs between 08:00:00 and 08:59:59).
crontab
# Edit your crontab: crontab -e
0 0 * * 1 /path/to/command
# With logging:
0 0 * * 1 /path/to/command >> /var/log/cron.log 2>&1 Variations
-
0 9 * * 1At 09:00 AM, only on Monday Monday at 09:00. If the output is read by people, this leaves a whole working day in which a failure can be spotted and re-run. -
0 0 * * MONAt 12:00 AM, only on Monday The same schedule using the day name. MON is far harder to misread than 1 in a code review, and every mainstream scheduler accepts it. -
0 0 * * 1,4At 12:00 AM, only on Monday and Thursday Monday and Thursday — twice a week, roughly halving the worst-case staleness of a weekly job for the cost of one more run. -
30 3 * * 1At 03:30 AM, only on Monday Monday at 03:30, inside the quiet window. Suits weekly maintenance that should be finished long before anyone opens a laptop.
Frequently asked questions
How do I read the cron expression 0 0 * * 1?
Read the five space-separated fields left to right as minute, hour, day of month, month, and day of week. In 0 0 * * 1 the minute is 0, hour is 0, day of month is *, month is *, day of week is 1. Of the operators cron defines, this expression uses only the ones that matter here: an asterisk matches every value in its field. Put together, cronstrue reads the whole thing as "At 12:00 AM, only on Monday", and a scheduler that checks all five fields once a minute will start the job one run per week.
What timezone does 0 0 * * 1 run in?
The expression carries no timezone of its own: it names hour 0, and the scheduler decides which hour 0 that is. Read as UTC, the run lands at 00:00 — 19:00 the previous day in New York, 00:00 in London, and 09:00 in Tokyo on a January date, with daylight saving moving the first two later in the year, so the same UTC instant is 20:00 the previous day in New York in July. That offset crosses a calendar day, and this schedule is pinned to a weekday, so the local weekday moves with it: the Monday run at 00:00 UTC happens at 19:00 on Sunday in New York. A job that reads the weekday back from the local clock there will disagree with the expression that scheduled it. Set the zone rather than converting by hand where you can: GitHub Actions defaults to UTC but takes an optional timezone key beside cron, and a Kubernetes CronJob has spec.timeZone, stable since 1.27. Where you cannot, convert deliberately: Vercel Cron is UTC-only, and a Linux crontab follows the host clock unless CRON_TZ overrides it.
Which number is Monday in a cron expression?
Monday is 1. The day-of-week field runs from 0 to 6 with Sunday at 0, so the week reads 0 Sunday, 1 Monday, 2 Tuesday, 3 Wednesday, 4 Thursday, 5 Friday, 6 Saturday. Many implementations also accept 7 as an alias for Sunday and the three-letter names MON through SUN, which are easier to review in a pull request. The numbering trips people up because ISO 8601 counts Monday as day 1 of the week and Sunday as day 7 — cron does not follow ISO, so read the day-of-week field carefully before trusting it.
Related cron schedules
-
0 0 * * 5Every Friday -
0 0 * * 1-5Every weekday -
0 0 * * 6,0Every weekend -
0 0 * * 0Every week -
0 0 1 * *Every month -
0 0 1 */3 *Every quarter
Build a custom schedule in the cron expression generator, or browse every epochkit tool.