The 0 0 * * 0 Expression
The cron expression 0 0 * * 0 fires at midnight every Sunday. Fields: minute (0), hour (0), day of month (*), month (*), day of week (0). Sunday occupies a unique position in cron’s day numbering: it is simultaneously 0 and 7. Understanding why that is the case gives you a clearer mental model of how the entire day of week field works.
Sunday Is Both 0 and 7: Here Is Why
POSIX cron defines days of the week as integers 0 through 6, with 0 being Sunday:
| Number | Day |
|---|---|
| 0 | Sunday |
| 1 | Monday |
| 2 | Tuesday |
| 3 | Wednesday |
| 4 | Thursday |
| 5 | Friday |
| 6 | Saturday |
| 7 | Sunday (alias) |
The problem with this numbering is range expressions that span the whole work week. Without the alias, you cannot write “Monday through Sunday” as a clean range. 1-0 is invalid and 1-6 would miss Sunday. Adding 7 as a Sunday alias makes 1-7 valid and unambiguous: Monday through Sunday.
Most production cron implementations (Vixie cron, cronie, fcron, systemd timers, AWS EventBridge, GCP Cloud Scheduler) accept both 0 and 7 for Sunday. Use 0 as the canonical value. Use 7 only when it makes a range expression cleaner.
The @weekly Shorthand
@weekly expands to 0 0 * * 0, midnight on Sunday. This is part of the Vixie cron extension set alongside @daily, @hourly, @monthly, and @reboot.
@weekly # equivalent to 0 0 * * 0
Other shorthands for context:
| Shorthand | Equivalent |
|---|---|
@weekly | 0 0 * * 0 |
@daily | 0 0 * * * |
@hourly | 0 * * * * |
@monthly | 0 0 1 * * |
@yearly | 0 0 1 1 * |
@weekly runs on Sunday, not Monday. If your mental model of “start of the week” is Monday, you want 0 0 * * 1, not @weekly.
Use Cases for Sunday Cron Jobs
Sunday sits at a natural boundary, either the end of the week (if your week runs Mon to Sun) or the beginning (if it runs Sun to Sat). Both framings produce useful scheduling patterns.
Weekly maintenance windows
Sunday midnight is the lowest traffic window for most consumer facing services. Database vacuums, index rebuilds, cache invalidation, and connection pool restarts are common Sunday jobs. The combination of low traffic and the full day ahead before Monday business hours means you have the maximum time to recover if something goes wrong.
Full database backups
Many teams run incremental backups daily and full backups weekly. Sunday midnight is the natural checkpoint. The full backup captures the entire previous week’s changes, and the Monday morning incremental starts a new cycle.
Log rotation and archiving
Weekly log archival (compressing the previous week’s logs, uploading to cold storage, purging local copies beyond a retention window) is a common Sunday job that keeps disk usage predictable.
Weekly summary reports
“Week in review” reports (aggregated metrics, usage statistics, error rate summaries) are often generated Sunday night or early Monday morning so they are ready at the start of the week. A 0 22 * * 0 (Sunday 10 PM) schedule gives the job enough time to finish before Monday standup.
Pre-Monday data preparation
Jobs that hydrate caches, precompute recommendations, or generate models benefit from running Sunday night. Users get faster responses Monday morning because the expensive computation already happened over the weekend.
Weekend-Only Pattern
0 0 * * 0,6 # midnight on Saturday and Sunday
Saturday is 6, Sunday is 0. They are not adjacent in the numbering, so you cannot use a range. You must use the comma form. A range like 0-6 covers Sunday through Saturday (all seven days), not just the weekend.
For weekend maintenance windows that can run on either day:
0 2 * * 0,6 # 2 AM Saturday and Sunday
0 4 * * 6,0 # 4 AM Saturday and Sunday (order in list is irrelevant)
Timezone Considerations
“End of week” processing is meaningless without pinning a timezone. A cron job running as 0 0 * * 0 on a UTC server fires at 00:00 UTC Sunday, which is Saturday evening in US timezones and Sunday morning in most of Asia. If your “weekly” job needs to align with a business timezone, two approaches:
Set the cron daemon’s timezone
On Linux systems running cronie, set CRON_TZ at the top of your crontab:
CRON_TZ=America/New_York
0 0 * * 0 # midnight Sunday, New York time
Convert the target time to UTC
If the cron daemon does not support timezone overrides, calculate the UTC equivalent and hardcode it:
0 5 * * 0 # midnight ET (UTC-5 in winter) expressed in UTC
The UTC conversion approach breaks during daylight saving time transitions. CRON_TZ or a system level timezone configuration is more robust.
Managed cloud schedulers (AWS EventBridge, GCP Cloud Scheduler) typically expose timezone configuration directly in their UI or IaC definitions, which is cleaner than working around it in the expression.
Verifying the Schedule
from croniter import croniter
from datetime import datetime
cron = croniter("0 0 * * 0", datetime.now())
for _ in range(5):
print(cron.get_next(datetime))
Each output should be a Sunday at 00:00:00. Use the cron builder on this page to see the next 10 run times and verify the schedule matches your expectation before deploying it.