Scheduling & Cron Jobs

Daita provides powerful scheduling capabilities to run your agents and workflows automatically at specified intervals. Schedules are configured using cron expressions and deployed to AWS EventBridge for reliable, managed execution.

#Overview

Schedule configuration allows you to:

  • Run agents and workflows on a recurring schedule (hourly, daily, weekly, etc.)
  • Set custom input data for scheduled executions
  • Control timezone for accurate scheduling
  • Enable/disable schedules without redeployment
  • Monitor scheduled task execution through the Daita dashboard

Schedules are defined in your daita-project.yaml file and automatically deployed to AWS EventBridge when you run daita push.

#Configuration

Define schedules in the schedules section of your daita-project.yaml:

yaml
schedules:
  agents:
    data_processor:
      cron: '0 */6 * * ? *' # Every 6 hours
      enabled: true
      timezone: 'UTC'
      description: 'Process accumulated data every 6 hours'
      data:
        batch_size: 1000
 
  workflows:
    backup_workflow:
      cron: '0 0 * * ? *' # Daily at midnight
      enabled: true
      timezone: 'UTC'
      description: 'Daily backup workflow'

#Configuration Fields

FieldTypeRequiredDescription
cronstringYesCron expression defining when to run
enabledbooleanNoWhether the schedule is active (default: true)
timezonestringNoTimezone for schedule (default: "UTC")
descriptionstringNoHuman-readable description of the schedule
dataobjectNoInput data to pass to the agent/workflow

#Cron Expression Format

Daita uses AWS EventBridge cron expressions, which require 6 fields (not the standard 5-field Unix format):

python
┌────────────── minute (0 - 59)
│ ┌────────────── hour (0 - 23)
│ │ ┌────────────── day of month (1 - 31)
│ │ │ ┌────────────── month (1 - 12 or JAN-DEC)
│ │ │ │ ┌────────────── day of week (1 - 7 or SUN-SAT)
│ │ │ │ │ ┌────────────── year (1970 - 2199)
│ │ │ │ │ │
* * * * ? *

Important differences from Unix cron:

  • 6 fields required - EventBridge adds a year field at the end
  • ? wildcard - Use ? for "any" in day-of-month or day-of-week fields. You cannot use * in both day fields
  • If you specify a day-of-week, use ? for day-of-month, and vice versa

#Common Patterns

yaml
# Every 15 minutes
cron: "*/15 * * * ? *"
 
# Every hour at minute 30
cron: "30 * * * ? *"
 
# Every 2 hours
cron: "0 */2 * * ? *"
 
# Every 6 hours (at 12am, 6am, 12pm, 6pm)
cron: "0 */6 * * ? *"
 
# Daily at 2:30 AM
cron: "30 2 * * ? *"
 
# Weekdays at 9 AM (use ? for day-of-month when day-of-week is specified)
cron: "0 9 ? * MON-FRI *"
 
# Every Monday at 9 AM
cron: "0 9 ? * MON *"
 
# First day of every month at midnight (use ? for day-of-week when day-of-month is specified)
cron: "0 0 1 * ? *"
 
# Every Sunday at midnight
cron: "0 0 ? * SUN *"
 
# Last day of the month is not directly supported
# Use daily job with date logic instead

#Named Days and Months

You can use names instead of numbers:

yaml
# Days: SUN, MON, TUE, WED, THU, FRI, SAT
cron: "0 9 ? * MON-FRI *"  # Weekdays
 
# Months: JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
cron: "0 0 1 JAN,JUL ? *"  # First day of January and July

#Examples

#Scheduled Agent with Custom Data

Process data every 6 hours with custom parameters:

yaml
schedules:
  agents:
    data_processor:
      cron: '0 */6 * * ? *'
      enabled: true
      timezone: 'UTC'
      description: 'Process accumulated data every 6 hours'
      data:
        batch_size: 1000
        mode: 'incremental'

Access scheduled data in your agent:

python
@agent()
def data_processor(inputs):
    batch_size = inputs.get('batch_size', 100)
    mode = inputs.get('mode', 'full')
 
    results = process_data(batch_size=batch_size, mode=mode)
    return {"status": "success", "count": len(results)}

#Weekly Reports

Run every Monday at 9 AM Eastern:

yaml
schedules:
  agents:
    report_generator:
      cron: '0 9 ? * MON *'
      enabled: true
      timezone: 'America/New_York'
      description: 'Generate weekly reports every Monday'
      data:
        report_type: 'weekly'

#Multiple Schedules for Same Agent

Use different schedule keys to run the same agent on different schedules:

yaml
schedules:
  agents:
    data_sync_frequent:
      cron: '0 9-17 ? * MON-FRI *'
      timezone: 'America/New_York'
      data:
        mode: 'incremental'
 
    data_sync_full:
      cron: '0 0 * * ? *'
      timezone: 'America/New_York'
      data:
        mode: 'full'

#Timezone Support

Schedules respect timezone configuration to ensure accurate execution timing:

yaml
schedules:
  agents:
    morning_report:
      cron: '0 9 ? * MON-FRI *'
      timezone: 'America/New_York' # 9 AM Eastern Time
 
    evening_cleanup:
      cron: '0 18 * * ? *'
      timezone: 'America/Los_Angeles' # 6 PM Pacific Time
 
    midnight_job:
      cron: '0 0 * * ? *'
      timezone: 'Europe/London' # Midnight UK time

#Common Timezones

  • UTC - Coordinated Universal Time
  • America/New_York - US Eastern Time
  • America/Chicago - US Central Time
  • America/Denver - US Mountain Time
  • America/Los_Angeles - US Pacific Time
  • Europe/London - UK Time
  • Europe/Paris - Central European Time
  • Asia/Tokyo - Japan Time
  • Australia/Sydney - Australian Eastern Time

See the full list of timezones for all supported values.

#Deployment

When you deploy with daita push, schedules are:

  1. Validated for correct cron syntax
  2. Created as AWS EventBridge rules
  3. Linked to your deployed agents/workflows

Deployment shows schedule confirmation:

bash
$ daita push
 Deploying to secure Lambda functions...
   Schedules: 2 agents, 1 workflow
 Deployed to production

The CLI validates schedules and shows errors if invalid.

#Managing Schedules

Enable/Disable:

yaml
schedules:
  agents:
    data_processor:
      enabled: true  # Active
    backup_agent:
      enabled: false # Disabled

Update Timing: Change the cron expression and deploy:

yaml
schedules:
  agents:
    report_generator:
      cron: '0 9 ? * MON-FRI *' # Updated from MON to MON-FRI

View Schedules:

bash
daita push --dry-run  # Preview schedules before deployment

Monitor Execution:

bash
daita logs data_processor          # View execution logs
daita logs data_processor --follow # Follow in real-time

Run daita push after any schedule changes to apply them.

#Environment-Specific Schedules

Use environment overrides to run schedules at different intervals per environment:

yaml
# Base configuration
schedules:
  agents:
    data_processor:
      cron: '0 */6 * * ? *' # Default: every 6 hours
      enabled: true
 
# Environment-specific overrides
environments:
  staging:
    schedules:
      agents:
        data_processor:
          cron: '0 */12 * * ? *' # Staging: every 12 hours
 
  production:
    schedules:
      agents:
        data_processor:
          cron: '0 */3 * * ? *' # Production: every 3 hours
          enabled: true

Deploy to specific environments:

bash
# Deploy to staging (uses 12-hour schedule)
daita push --env staging
 
# Deploy to production (uses 3-hour schedule)
daita push --env production

#Best Practices

Configuration:

  • Always include clear descriptions for each schedule
  • Use timezones that match your business operations
  • Test with daita push --dry-run before deploying

Frequency:

  • Avoid over-scheduling (minimum recommended: every 15 minutes)
  • Don't schedule every minute - may cause throttling
  • Stagger multiple schedules to avoid resource contention

Agent Code:

  • Provide defaults for all scheduled input parameters
  • Handle errors gracefully and return status information
  • Make scheduled executions idempotent when possible

Monitoring:

  • Regularly check execution logs: daita logs <agent-name>
  • Monitor for failures: daita logs <agent-name> | grep -i error
  • Set up alerts for critical scheduled tasks

#Troubleshooting

Schedule Not Executing:

  • Verify enabled: true is set
  • Check cron expression is valid (6 fields required)
  • Confirm timezone matches expected execution time
  • Review deployment logs for errors

Wrong Execution Time:

  • Verify timezone setting (use 24-hour format)
  • Check if daylight saving time affects your timezone
  • Remember EventBridge uses 6-field cron (not standard 5-field)
  • Use ? correctly for day-of-month or day-of-week

Execution Failures:

  • Check agent handles scheduled inputs with proper defaults
  • Verify scheduled data fields match agent expectations
  • Review error logs: daita logs <agent-name>

Changes Not Applied:

  • Run daita push after configuration changes
  • Verify YAML syntax (check indentation)
  • Look for validation errors in deployment output

#Limitations

#Frequency Constraints

  • Minimum interval: 1 minute (cron expressions with * * * * *)
  • Maximum frequency: Avoid sub-minute intervals
  • Rate limits: AWS EventBridge limits apply (check current quotas)

#Cron Expression Support

EventBridge 6-field cron format required:

  • ✅ Supported: 0 */6 * * ? * (every 6 hours)
  • ✅ Supported: 0 9 ? * MON-FRI * (weekdays at 9 AM)
  • ✅ Supported: Named days/months (MON-FRI, JAN-DEC)
  • ✅ Supported: Ranges (9-17 for hours 9 AM to 5 PM)
  • ❌ Not supported: L for last day of month (use daily job with date logic)
  • ❌ Not supported: @daily, @hourly macros (use standard cron format)
  • ❌ Not supported: * in both day-of-month and day-of-week (use ? for one)

#EventBridge Limits

AWS EventBridge quotas apply:

  • Rules per account: 300 by default (can be increased)
  • Invocations per second: Varies by region
  • See AWS EventBridge Quotas

#Next Steps