← Blog  ·  October 2026

Cron Expression Examples: 60+ Real-World Cron Schedules

60+ copy-paste-ready cron expressions for real-world tasks: backups, reports, deployments, cache warmups, cleanups, and more.

Cron expressions are one of those things you reach for repeatedly but never quite commit to memory. This page has two parts: real-world use cases (specific tasks with the cron expression that fits) and a complete reference organized by schedule frequency. If you know what you need to schedule but can’t remember the syntax, start with the use cases.

The five fields (standard cron)
*minute
0–59
*hour
0–23
*day of month
1–31
*month
1–12
*day of week
0–7 (0,7=Sun)
Not sure about an expression? Paste it into the cron expression parser to see the plain-English description, field-level validation, and next 5 run times in your local timezone.

Real-world use cases

The right schedule depends on what the job does. Here are common real-world tasks with the cron expression that fits each one.

System maintenance

TaskExpressionNotes
Nightly database backup0 2 * * *2am daily — low traffic, before business hours
Weekly full backup (off-peak)0 1 * * 0Sunday 1am; run shorter incrementals Mon–Sat
Log rotation / cleanup0 0 * * *Midnight daily; clears yesterday’s logs
Temp file purge30 3 * * *3:30am — after backup finishes, before day starts
SSL certificate renewal check0 0 * * 1Weekly Monday; certbot renews ~30 days before expiry
Disk usage alert0 */6 * * *Every 6 hours; alerts if disk > 85%
Security scan0 3 * * 0Sunday 3am weekly; avoid running during business hours
Database VACUUM / ANALYZE0 4 * * 0Sunday 4am; Postgres autovacuum may handle this already

Application jobs

TaskExpressionNotes
Daily email digest0 8 * * *8am UTC; users receive digest at the start of their day
Weekly summary report0 9 * * 1Monday 9am; lands in inboxes at start of work week
Monthly invoice generation0 6 1 * *1st of month at 6am; before customers check email
Subscription renewal reminders0 10 * * *Daily at 10am; script filters which users expire in 7 days
Failed payment retry0 */4 * * *Every 4 hours; retry with exponential backoff in code
Abandoned cart email30 1 * * *1:30am daily; catch carts abandoned >24h ago
Review request (e-commerce)0 10 * * 1-5Weekday mornings; higher open rates than weekends

Data pipelines and syncs

TaskExpressionNotes
ETL from external API0 */2 * * *Every 2 hours; respect API rate limits and TTL
CRM / database sync*/30 * * * *Every 30 minutes during the day; full sync nightly
Search index rebuild0 3 * * *3am nightly; avoid during peak search traffic
Analytics aggregation5 0 * * *12:05am; after midnight boundary, aggregates yesterday’s data
Cache warmup (CDN/Redis)50 5 * * *5:50am; warms before 6am traffic spike begins
Sitemap regeneration0 1 * * *1am nightly; submit fresh sitemap to search engines
Exchange rate / price update0 */1 * * *Hourly; or */15 9-17 * * 1-5 during market hours only
Quarterly data export0 6 1 */3 *First day of each quarter (Jan, Apr, Jul, Oct) at 6am

CI/CD and deployment jobs

TaskExpressionNotes
Nightly build / test suite0 2 * * *2am; run full suite overnight, report by 6am
Dependency update check0 9 * * 1Monday 9am; opens PRs for outdated packages weekly
Staging environment reset0 0 * * *Midnight; resets staging to prod snapshot for clean tests
Automated smoke test*/15 * * * *Every 15 minutes; quick end-to-end health check
Docker image cleanup0 4 * * 0Sunday 4am; prunes dangling images / old containers
Kubernetes node health check*/5 * * * *Every 5 minutes; escalate if node not ready >10 min

Monitoring and alerting

TaskExpressionNotes
Uptime check*/5 * * * *Every 5 minutes; dedicated tools (Uptime Robot) are better
Dead link checker0 0 * * 0Weekly Sunday midnight; broken link scan across the site
Error rate alert*/10 * * * *Every 10 minutes; check Sentry/Datadog error counts
Daily metrics email0 7 * * 1-5Weekday 7am; key business metrics before standup
API budget check0 0 * * *Daily midnight; alert if approaching API quota limits

Every N minutes

ExpressionMeaning
* * * * *Every minute
*/2 * * * *Every 2 minutes
*/5 * * * *Every 5 minutes
*/10 * * * *Every 10 minutes
*/15 * * * *Every 15 minutes
*/30 * * * *Every 30 minutes

The */n syntax means "every n units." */15 * * * * fires at :00, :15, :30, and :45 of each hour. Note that */7 * * * * does not fire "every 7 minutes consistently" — it fires at minutes 0, 7, 14, 21, 28, 35, 42, 49, 56, and then resets at the top of the next hour. If consistent intervals across hours matter, use a different approach.


Every N hours

ExpressionMeaning
0 * * * *Every hour (at :00)
0 */2 * * *Every 2 hours
0 */4 * * *Every 4 hours (midnight, 4am, 8am, noon, 4pm, 8pm)
0 */6 * * *Every 6 hours (midnight, 6am, noon, 6pm)
0 */12 * * *Every 12 hours (midnight and noon)
30 */4 * * *Every 4 hours, at :30 past the hour

Daily schedules

ExpressionMeaning
0 0 * * *Every day at midnight (12:00 AM)
0 1 * * *Every day at 1:00 AM
0 3 * * *Every day at 3:00 AM
0 6 * * *Every day at 6:00 AM
0 9 * * *Every day at 9:00 AM
0 12 * * *Every day at noon (12:00 PM)
0 17 * * *Every day at 5:00 PM
0 23 * * *Every day at 11:00 PM
30 8 * * *Every day at 8:30 AM
15 14 * * *Every day at 2:15 PM

The @daily shorthand is equivalent to 0 0 * * * on most systems.


Weekday-only schedules

ExpressionMeaning
0 9 * * 1-5Every weekday (Mon–Fri) at 9:00 AM
0 8 * * 1-5Every weekday at 8:00 AM
0 18 * * 1-5Every weekday at 6:00 PM
*/30 9-17 * * 1-5Every 30 minutes during business hours (9am–5pm), weekdays
0 0 * * 6,0Every weekend (Saturday and Sunday) at midnight
0 10 * * 1Every Monday at 10:00 AM
0 10 * * 5Every Friday at 10:00 AM

In standard cron, 1-5 means Monday through Friday. Day-of-week values: 0 or 7 = Sunday, 1 = Monday, …, 6 = Saturday.

Gotcha: AND vs. OR semantics When you specify both day-of-month and day-of-week (i.e., neither is *), cron uses OR logic — the job runs if either condition matches. 0 12 15 * 5 fires on the 15th of every month and on every Friday. To get AND semantics (only on Fridays that fall on the 15th), you need a script-level check: run [ $(date +%d) -eq 15 ] && your-command.

Weekly schedules

ExpressionMeaning
0 0 * * 0Every Sunday at midnight
0 9 * * 1Every Monday at 9:00 AM
0 10 * * 3Every Wednesday at 10:00 AM
0 8 * * 6Every Saturday at 8:00 AM
0 2 * * 0Every Sunday at 2:00 AM (weekly maintenance window)

The @weekly shorthand is equivalent to 0 0 * * 0.


Monthly schedules

ExpressionMeaning
0 0 1 * *First day of every month at midnight
0 9 1 * *First day of every month at 9:00 AM
0 0 15 * *15th of every month at midnight
0 0 L * *Last day of every month (Quartz/Spring syntax — not standard cron)
0 0 1 */3 *First day of every quarter (Jan, Apr, Jul, Oct) at midnight
0 0 1 1 *January 1st at midnight (yearly)
February edge case 0 0 28-31 * * does not reliably mean "last day of the month." In February, day 28 exists every year, but days 29–31 don't. The job will still fire on the 28th — and on days 29, 30, 31 in months that have them. For last-day-of-month logic, use a wrapper script: [ $(date +%d) -eq $(cal | awk 'NF{f=$NF} END{print f}') ] && your-command.

Specific times and patterns

ExpressionMeaning
0,30 * * * *Every hour at :00 and :30
0 6,12,18 * * *Three times daily: 6am, noon, 6pm
0 0 * * 1,3,5Monday, Wednesday, Friday at midnight
0 9-17 * * 1-5Every hour from 9am to 5pm, weekdays
5 4 * * 0Every Sunday at 4:05 AM
23 */2 * * *At minute 23 of every even-numbered hour
0 4 1,15 * *1st and 15th of every month at 4:00 AM

Commas in any field mean "or" — 1,3,5 in the day-of-week field means Monday, Wednesday, or Friday.


@-shorthand expressions

Most cron implementations support convenient @-shorthands:

ShorthandEquivalentMeaning
@yearly0 0 1 1 *Once a year, January 1st at midnight
@annually0 0 1 1 *Same as @yearly
@monthly0 0 1 * *Once a month, first day at midnight
@weekly0 0 * * 0Once a week, Sunday at midnight
@daily0 0 * * *Once a day at midnight
@midnight0 0 * * *Same as @daily
@hourly0 * * * *Once an hour at :00
@rebootN/AOnce, at system startup (not supported everywhere)

Platform-specific examples

GitHub Actions

GitHub Actions uses standard 5-field cron syntax in UTC. The schedule trigger fires approximately on time but not exactly — GitHub queues jobs during high-load periods.

on:
  schedule:
    - cron: '0 6 * * 1-5'     # Weekdays at 6:00 AM UTC
    - cron: '*/15 * * * *'    # Every 15 minutes (note: not recommended for high-frequency polling)
    - cron: '0 0 * * 0'       # Weekly on Sunday at midnight UTC

Important: GitHub Actions cron jobs that haven't run for 60 days on an inactive repository will be disabled automatically.

AWS EventBridge (CloudWatch Events)

AWS supports two formats: cron (6 fields, with year) and rate expressions.

# AWS cron format: cron(minute hour day-of-month month day-of-week year)
cron(0 9 * * ? *)          # Every day at 9:00 AM UTC (? = no specific day-of-week)
cron(0 */4 * * ? *)        # Every 4 hours
cron(0 0 1 * ? *)          # First day of every month at midnight

# Rate expressions (simpler for intervals)
rate(5 minutes)
rate(1 hour)
rate(1 day)

AWS uses ? (not *) when day-of-month and day-of-week conflict. You must use ? in one of the two fields when the other is specified.

Kubernetes CronJob

Kubernetes uses standard 5-field cron syntax in the server's local timezone (usually UTC).

apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-report
spec:
  schedule: "0 3 * * *"       # Every day at 3:00 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: report
            image: myapp:latest
            command: ["python", "report.py"]

Node.js (node-cron)

The popular node-cron library uses a 5 or 6-field format (optionally with seconds as the first field):

import cron from 'node-cron';

// Standard 5-field
cron.schedule('0 * * * *', () => console.log('Every hour'));
cron.schedule('*/5 * * * *', () => console.log('Every 5 minutes'));

// 6-field (with seconds as first field)
cron.schedule('*/30 * * * * *', () => console.log('Every 30 seconds'));

Common mistakes and gotchas

Minutes vs. hours confusion

0 */4 * * * (every 4 hours) is not the same as */4 0 * * * (every 4 minutes during the midnight hour only). The order matters: minute, hour, day, month, weekday.

Timezone blind spots

Standard cron runs in the server's local timezone. If your server is UTC and you want a job to run at 9am New York time (EST/EDT), you need to account for the offset: 0 14 * * * in UTC for EST (+5), 0 13 * * * for EDT (+4). Daylight saving transitions can cause jobs to shift by an hour.

The "every minute on the 0th minute of an hour" trap

0 * * * * fires once an hour, not once a minute. * * * * * fires every minute. A single 0 in the minute field means "at minute 0 (the top of the hour)."

Jobs that take longer than their interval

If your job takes 45 minutes and runs every 30 minutes, you'll have overlapping runs. Most cron implementations don't enforce single-instance behavior — add a lock file or use flock:

*/30 * * * * flock -n /tmp/myjob.lock /opt/jobs/myjob.sh

🕐 Validate your cron expression

Paste any expression into the free cron parser to see a plain-English description, field-level validation, and the next 5 run times in your local timezone. Works offline, no signup.

Open cron expression parser →

Know when your cron jobs stop running

Getting the expression right is half the job. The harder part — and the one that actually causes incidents — is knowing when a scheduled job quietly stops running. Cron doesn't alert you when a job misses its window. It just doesn't run.

The pattern that works: a dead man's switch. Your cron job sends an HTTP ping at the end of each successful run. If the monitoring service doesn't receive the ping within the expected window, it alerts you. One line at the end of your job catches three failure modes at once: the job didn't start, the job failed, or the job was killed before completing.

📟 CronWatch — alerts when jobs stop running

CronWatch adds a dead man's switch to your existing cron jobs. Add one curl line to your script. If the job misses its window, you get an alert. Works with crontab, GitHub Actions, Heroku Scheduler, AWS EventBridge, and Kubernetes CronJob.

Join the CronWatch waitlist → Parse an expression

← All articles  ·  CronWatch  ·  Cron parser tool