Back to Home

Cron Expression: Every Day at Midnight (0 0 * * *)

CronOS Team
cronschedulingdailymidnighttutorial

Need to generate a cron expression?

Use CronOS to generate any cron expression you wish with natural language. Simply describe what you need, and we'll create the perfect cron expression for you. It's completely free!

Generate Cron Expression

Cron Expression: Every Day at Midnight (0 0 * * *)

The cron expression 0 0 * * * executes a task every day at midnight (00:00), making it one of the most commonly used patterns for daily backups, reports, cleanup operations, and data processing tasks.

Expression Breakdown

bash
0 0 * * *
│ │ │ │ │
│ │ │ │ └─── Day of week: * (every day)
│ │ │ └───── Month: * (every month)
│ │ └─────── Day of month: * (every day)
│ └───────── Hour: 0 (at hour 0, midnight)
└─────────── Minute: 0 (at minute 0)

Field Values

FieldValueMeaning
Minute0At minute 0
Hour0At hour 0 (midnight)
Day of Month*Every day (1-31)
Month*Every month (1-12)
Day of Week*Every day of week (0-7)

Execution Time

This expression runs once per day at:

  • 00:00 (midnight)

Common Use Cases

1. Daily Backups

bash
0 0 * * * /usr/local/bin/daily-backup.sh

Create full backups of databases, files, or entire systems at midnight.

2. Daily Reports

bash
0 0 * * * /usr/bin/python3 /scripts/generate-daily-report.py

Generate daily analytics reports, summaries, or data aggregations.

3. Log Rotation

bash
0 0 * * * /usr/local/bin/rotate-logs.sh

Rotate, compress, or archive log files daily.

4. Database Maintenance

bash
0 0 * * * /usr/local/bin/db-maintenance.sh

Run database cleanup, optimization, or maintenance tasks.

5. Cache Cleanup

bash
0 0 * * * /usr/bin/python3 /scripts/cleanup-cache.py

Clear or refresh cached data at the start of each day.

6. Data Processing

bash
0 0 * * * /usr/bin/python3 /scripts/process-daily-data.py

Process daily data batches, ETL operations, or data transformations.

Example Implementations

Daily Backup Script

bash
#!/bin/bash
# /usr/local/bin/daily-backup.sh

BACKUP_DIR="/var/backups/daily"
SOURCE_DIR="/var/data"
TIMESTAMP=$(date +%Y%m%d)
LOG_FILE="/var/log/backups.log"

mkdir -p $BACKUP_DIR

# Create daily backup
tar -czf "$BACKUP_DIR/backup_$TIMESTAMP.tar.gz" \
    -C $(dirname $SOURCE_DIR) \
    $(basename $SOURCE_DIR) >> $LOG_FILE 2>&1

# Database backup (if using PostgreSQL)
# pg_dump -U dbuser app_db | gzip > "$BACKUP_DIR/db_backup_$TIMESTAMP.sql.gz"

# Clean up backups older than 30 days
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete

echo "$(date): Daily backup completed" >> $LOG_FILE

Python Daily Report

python
# generate-daily-report.py
import json
from datetime import datetime, timedelta
import sqlite3

def generate_daily_report():
    conn = sqlite3.connect('/var/data/app.db')
    cursor = conn.cursor()
    
    # Get data from yesterday
    yesterday = datetime.now() - timedelta(days=1)
    start_date = yesterday.replace(hour=0, minute=0, second=0)
    end_date = yesterday.replace(hour=23, minute=59, second=59)
    
    # Aggregate metrics
    cursor.execute('''
        SELECT 
            COUNT(*) as total_requests,
            AVG(response_time) as avg_response_time,
            COUNT(CASE WHEN status_code >= 400 THEN 1 END) as errors,
            COUNT(CASE WHEN status_code >= 500 THEN 1 END) as server_errors
        FROM requests
        WHERE timestamp >= ? AND timestamp <= ?
    ''', (start_date, end_date))
    
    metrics = cursor.fetchone()
    
    report = {
        'date': yesterday.strftime('%Y-%m-%d'),
        'total_requests': metrics[0],
        'avg_response_time': round(metrics[1], 2) if metrics[1] else 0,
        'errors': metrics[2],
        'server_errors': metrics[3],
        'error_rate': round((metrics[2] / metrics[0] * 100), 2) if metrics[0] > 0 else 0
    }
    
    # Save report
    report_file = f'/var/reports/daily_report_{yesterday.strftime("%Y%m%d")}.json'
    with open(report_file, 'w') as f:
        json.dump(report, f, indent=2)
    
    print(f"{datetime.now()}: Daily report generated for {yesterday.strftime('%Y-%m-%d')}")
    conn.close()

if __name__ == '__main__':
    generate_daily_report()

Log Rotation Script

bash
#!/bin/bash
# /usr/local/bin/rotate-logs.sh

LOG_DIR="/var/log/app"
ARCHIVE_DIR="/var/log/archive"
RETENTION_DAYS=30

mkdir -p $ARCHIVE_DIR

# Rotate logs
for logfile in $LOG_DIR/*.log; do
    if [ -f "$logfile" ]; then
        filename=$(basename $logfile)
        archive_path="$ARCHIVE_DIR/${filename}.$(date +%Y%m%d).gz"
        
        # Compress and archive
        gzip -c $logfile > $archive_path
        
        # Truncate original log
        > $logfile
        
        echo "$(date): Rotated $filename"
    fi
done

# Clean up old archives
find $ARCHIVE_DIR -name "*.gz" -mtime +$RETENTION_DAYS -delete

Best Practices

  1. System Load: Midnight is often a low-traffic period, ideal for heavy operations
  2. Error Handling: Implement comprehensive error handling and logging
  3. Locking: Use file locks to prevent concurrent execution
  4. Monitoring: Set up alerts for failed daily jobs
  5. Resource Management: Monitor CPU, memory, and I/O usage
  6. Backup Verification: Verify backups after creation

When to Use

Good for:

  • Daily backups
  • Report generation
  • Log rotation
  • Database maintenance
  • Cache cleanup
  • Data processing
  • ETL operations

Avoid for:

  • Real-time critical operations
  • Tasks requiring immediate execution
  • Very long-running processes (over 23 hours)

Related Patterns

PatternExpressionDescription
Daily at 1 AM0 1 * * *One hour after midnight
Daily at 8 AM0 8 * * *Start of business day
Daily at noon0 12 * * *Midday
Daily at 6 PM0 18 * * *End of business day

Conclusion

The 0 0 * * * expression is perfect for daily maintenance tasks that should run at midnight. It's one of the most commonly used cron patterns in production environments, ideal for backups, reports, and cleanup operations that need to run once per day during low-traffic periods.

Need to generate a cron expression?

Use CronOS to generate any cron expression you wish with natural language. Simply describe what you need, and we'll create the perfect cron expression for you. It's completely free!

Generate Cron Expression