Cron Parser: Decode Any Cron Expression

📅 April 13, 2026 ⏱ 9 min read ✍️ Risetop Team

You've seen them in server configs, CI/CD pipelines, and cloud dashboards: cryptic strings like 30 4 * * 6 or 0 */6 * * *. These are cron expressions — the scheduling language that powers virtually every automated task on Linux systems and cloud platforms. If you can read cron, you can understand when any scheduled job runs, debug timing issues, and write schedules with confidence.

This guide teaches cron expressions through 5 real-world scenarios. Instead of memorizing syntax, you'll learn by doing — each scenario presents a real operations problem, walks through the cron solution, and explains every field.

🔍 Paste any cron expression and get instant human-readable output + next execution times.

Parse Cron Expression Now

Cron Syntax: The 5-Minute Refresher

A standard cron expression has 5 fields, separated by spaces:

FieldValuesDescription
Minute0-59Minute of the hour
Hour0-23Hour of the day (24-hour format)
Day of Month1-31Day of the month
Month1-12Month of the year
Day of Week0-6 (0 = Sunday)Day of the week

Special characters: * (any value), , (list), - (range), / (step). Now let's apply this to real scenarios.

SCENARIO 1

Linux System Maintenance

The problem: You manage a fleet of Linux servers. Every Sunday at 3:00 AM, you need to run system updates, clean package caches, and check disk space. During business hours, these tasks would slow down production. You need a cron schedule that runs reliably every weekend.

0 3 * * 0
"At 03:00 AM, every Sunday"

Field breakdown:

The crontab entry:

# Weekly system maintenance
0 3 * * 0 /usr/local/bin/system-maintenance.sh >> /var/log/maintenance.log 2>&1

Pro tips for this scenario:

SCENARIO 2

Automated Database Backups

The problem: Your PostgreSQL database needs daily backups. Backups should run at 2:30 AM every day (after the nightly ETL pipeline finishes at 2:00 AM). You also want weekly full backups on Saturdays and monthly archive backups on the 1st of each month.

Daily incremental backup:

30 2 * * *
"At 02:30 AM, every day"

Weekly full backup:

0 3 * * 6
"At 03:00 AM, every Saturday"

Monthly archive:

0 4 1 * *
"At 04:00 AM, on day 1 of every month"

The crontab entries:

# Daily incremental backup
30 2 * * * pg_dump -Fc mydb | gzip > /backups/daily/mydb-$(date +\%Y\%m\%d).sql.gz

# Weekly full backup
0 3 * * 6 pg_dump -Fc mydb | gzip > /backups/weekly/mydb-week-$(date +\%Y\%W).sql.gz

# Monthly archive
0 4 1 * * pg_dump -Fc mydb | gzip > /backups/monthly/mydb-$(date +\%Y\%m).sql.gz

Key insight: The $(date +\%Y\%m\%d) creates timestamped filenames. Note the \% escaping — cron requires percent signs to be escaped in commands.

Rotation strategy: Add a cleanup job that removes backups older than 30 days:

0 5 * * * find /backups/daily -name "*.sql.gz" -mtime +30 -delete
SCENARIO 3

Data Synchronization Between Services

The problem: You have a microservices architecture where Service A is the source of truth for user profiles. Service B needs to sync user data every 15 minutes during business hours (9 AM - 6 PM, Monday through Friday). Running the sync 24/7 would waste resources; running it only during business hours keeps the data fresh enough for real-time features.

*/15 9-18 * * 1-5
"Every 15 minutes, between 09:00 AM and 06:00 PM, Monday through Friday"

Field breakdown:

Next execution times for this schedule:

Mon 09:00, Mon 09:15, Mon 09:30, ..., Mon 18:00, Mon 18:15, Mon 18:30, Mon 18:45
Tue 09:00, Tue 09:15, ...
(No executions on weekends or outside 9 AM - 6:45 PM)

Pro tips:

SCENARIO 4

Scheduled Email Reports

The problem: Your sales team wants a weekly performance summary email every Monday at 8:00 AM, giving them time to review before the Monday standup at 9:30 AM. They also want a monthly executive report on the last day of every month at 4:00 PM.

Weekly sales report:

0 8 * * 1
"At 08:00 AM, every Monday"

Monthly executive report:

0 16 28-31 * *
"At 04:00 PM, on day 28-31 (handles months with 28-31 days)"

The tricky part: Cron doesn't have a "last day of month" operator. Using 28-31 means the job runs on days 28, 29, 30, and 31. To run only on the actual last day, wrap the command in a shell check:

# Monthly executive report (runs on actual last day of month)
0 16 28-31 * * [ $(date -d "+1 day" +\%d) -eq 01 ] && /usr/local/bin/executive-report.sh

This checks if tomorrow is the 1st — if so, today must be the last day of the month. Elegant and reliable.

SCENARIO 5

Automated Log Cleanup

The problem: Your application generates 500MB of logs per day across multiple services. Without cleanup, disk space fills up in weeks. You need to rotate and compress logs daily, and delete old logs after 90 days. The cleanup should run at midnight when traffic is lowest.

0 0 * * *
"At 00:00 AM (midnight), every day"

The crontab entries:

# Compress yesterday's logs
0 0 * * * find /var/log/app -name "*.log" -mtime +1 -exec gzip {} \;

# Delete logs older than 90 days
0 0 * * * find /var/log/app -name "*.log.gz" -mtime +90 -delete

# Also clean up temp files older than 7 days
0 0 * * * find /tmp/app-* -mtime +7 -delete

Better approach — use logrotate:

While cron works, most Linux systems have logrotate built in, which handles compression, rotation, and retention automatically. Create a config file at /etc/logrotate.d/myapp:

/var/log/app/*.log {
    daily
    rotate 90
    compress
    delaycompress
    missingok
    notifempty
    create 0644 www-data www-data
}

Then a single cron entry triggers logrotate daily:

0 0 * * * /usr/sbin/logrotate /etc/logrotate.conf

Common Cron Pitfalls and How to Avoid Them

⏰ Decode any cron expression instantly — see human-readable descriptions and next run times.

Parse Your Cron Expression

Frequently Asked Questions

What does a cron expression look like?
A standard cron expression has 5 fields separated by spaces: minute, hour, day of month, month, and day of week. For example, '0 2 * * *' means 'run at 2:00 AM every day'. Some systems (like Quartz for Java) use 6 or 7 fields to include seconds and years.
What is the difference between * and ? in cron?
In standard Linux cron, there is no '?' character — use '*' for any value. In some implementations like Quartz (Java/Spring), '?' means 'no specific value' and is required in the day-of-month or day-of-week field when the other is specified to avoid conflicts.
How do I schedule a cron job to run every 5 minutes?
Use '*/5 * * * *'. The */5 syntax means 'every 5th value' in the minute field, so it runs at minutes 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, and 55. Similarly, '*/15 * * * *' runs every 15 minutes and '*/30 * * * *' runs every 30 minutes.
Can cron run jobs at second-level precision?
Standard Linux cron has minute-level granularity — the smallest interval is 1 minute. For second-level scheduling, consider systemd timers, or use cron implementations with 6-field syntax. Some cloud platforms (AWS EventBridge, Google Cloud Scheduler) also support sub-minute intervals.
How do I test a cron expression without waiting?
Use an online cron parser like Risetop's Cron Parser — it instantly shows the human-readable description and next 10 execution times. You can also temporarily set the cron to run 1-2 minutes from now and check your logs, or use tools like 'croniter' in Python to programmatically verify schedules.