Overview
The @schedule decorator specifies when a flow should run automatically when deployed to a production orchestrator (AWS Step Functions or Argo Workflows).
This is a flow-level decorator and must be placed above the FlowSpec class definition.
Basic Usage
from metaflow import FlowSpec, step, schedule
@schedule ( daily = True )
class DailyReportFlow ( FlowSpec ):
@step
def start ( self ):
print ( "Generating daily report..." )
self .next( self .end)
@step
def end ( self ):
pass
Parameters
Run the workflow every hour
Run the workflow every day at midnight UTC
Run the workflow every Sunday at midnight UTC
Custom cron expression for AWS EventBridge or Argo Workflows schedule. For AWS Step Functions, uses EventBridge cron format . For Argo Workflows, uses standard cron format.
Timezone for the schedule in IANA format (e.g., America/Los_Angeles). Currently only supported for Argo Workflows. AWS Step Functions schedules run in UTC.
Predefined Schedules
Hourly
@schedule ( hourly = True )
class HourlyETL ( FlowSpec ):
pass
Runs every hour: 0 * * * ? *
Daily
@schedule ( daily = True ) # This is the default
class DailyProcessing ( FlowSpec ):
pass
Runs every day at midnight UTC: 0 0 * * ? *
Weekly
@schedule ( weekly = True )
class WeeklyReport ( FlowSpec ):
pass
Runs every Sunday at midnight UTC: 0 0 ? * SUN *
Custom Cron Expressions
AWS Step Functions Cron
AWS EventBridge uses a 6-field cron expression:
@schedule ( cron = '0 9 * * ? *' ) # Every day at 9 AM UTC
class MorningReport ( FlowSpec ):
pass
Format: minute hour day-of-month month day-of-week year
Examples:
0 9 * * ? * - Every day at 9 AM UTC
0 12 ? * MON-FRI * - Weekdays at noon UTC
0 0 1 * ? * - First day of every month at midnight UTC
0/15 * * * ? * - Every 15 minutes
Argo Workflows Cron with Timezone
Argo supports standard 5-field cron with timezone:
@schedule (
cron = '0 9 * * *' , # 9 AM in specified timezone
timezone = 'America/Los_Angeles'
)
class TimezoneAwareFlow ( FlowSpec ):
pass
Format: minute hour day month day-of-week
Examples:
0 9 * * * - Every day at 9 AM
0 12 * * 1-5 - Weekdays at noon
0 0 1 * * - First day of every month
*/15 * * * * - Every 15 minutes
Deployment
Deploy to AWS Step Functions
# Deploy with schedule
python flow.py step-functions create
# The schedule is automatically configured
Deploy to Argo Workflows
# Deploy with schedule
python flow.py argo-workflows create
# The CronWorkflow is automatically created
Examples
Business Hours Report
from metaflow import FlowSpec, step, schedule
@schedule ( cron = '0 9,12,15,18 ? * MON-FRI *' ) # 9 AM, noon, 3 PM, 6 PM on weekdays
class BusinessHoursReport ( FlowSpec ):
@step
def start ( self ):
from datetime import datetime
self .timestamp = datetime.now().isoformat()
print ( f "Report generated at { self .timestamp } " )
self .next( self .end)
@step
def end ( self ):
pass
Monthly Data Processing
@schedule ( cron = '0 2 1 * ? *' ) # 2 AM on the first day of each month
class MonthlyAggregation ( FlowSpec ):
@step
def start ( self ):
from datetime import datetime
self .month = datetime.now().strftime( '%Y-%m' )
print ( f "Processing data for { self .month } " )
self .next( self .end)
@step
def end ( self ):
pass
International Sync (Timezone-Aware)
@schedule (
cron = '0 8 * * 1' , # Monday at 8 AM
timezone = 'Europe/London'
)
class InternationalSync ( FlowSpec ):
@step
def start ( self ):
print ( "Syncing international data..." )
self .next( self .end)
@step
def end ( self ):
pass
Combining with Other Decorators
from metaflow import FlowSpec, step, schedule, project
@project ( name = 'data-platform' )
@schedule ( daily = True )
class ScheduledProjectFlow ( FlowSpec ):
@step
def start ( self ):
self .next( self .end)
@step
def end ( self ):
pass
Best Practices
Use UTC for AWS schedules
AWS Step Functions schedules always run in UTC, so plan accordingly: # If you want 9 AM Eastern (EST/EDT), use UTC
@schedule ( cron = '0 14 * * ? *' ) # 9 AM EST = 2 PM UTC (EST)
# Note: Adjust for daylight saving time manually
Use timezone for global teams
When working with Argo Workflows across timezones: @schedule (
cron = '0 9 * * *' ,
timezone = 'America/New_York'
)
Avoid high-frequency schedules
Be cautious with very frequent schedules: # Good - hourly
@schedule ( hourly = True )
# Use with caution - every 5 minutes
@schedule ( cron = '*/5 * * * ? *' )
Test schedule logic locally
Test your flow’s schedule-dependent logic locally: @step
def start ( self ):
from datetime import datetime
# This works both locally and in scheduled runs
self .run_time = datetime.now()
Production Deployment Learn about deploying to production
Scheduling Guide Complete guide to scheduling flows
AWS Step Functions Deploy to AWS Step Functions
Argo Workflows Deploy to Argo Workflows