What are Schedules?
Schedules allow you to automatically trigger workflow executions at specified times or intervals. Instead of manually starting workflows, you can configure them to run:- On a cron schedule: Run at specific times (e.g., every day at 9 AM)
- At regular intervals: Run repeatedly with a fixed delay (e.g., every 5 minutes)
- On calendar dates: Run on specific days of the month or week
Key Features
Multiple Schedule Types
Choose from cron expressions, intervals, or calendar-based scheduling.
Overlap Policies
Control what happens when a new run is triggered while a previous run is still executing.
Dynamic Management
Create, pause, resume, and delete schedules at runtime without redeploying.
Backfill Support
Catch up on missed runs after downtime with backfill capabilities.
Creating Schedules
There are two ways to create schedules:Using the Decorator
The@scheduled_workflow decorator combines workflow definition with schedule configuration:
- Cron Schedule
- Interval Schedule
- With Options
Using the API
For dynamic schedule creation, use thecreate_schedule function:
Schedule Types
Cron Expressions
Cron expressions provide precise control over when workflows run. The format is:Intervals
Intervals specify a fixed duration between runs:s- secondsm- minutesh- hoursd- days
When using intervals, the first run happens immediately when the schedule is created. Subsequent runs occur at the specified interval after each run completes.
Calendar-Based Schedules
For more complex scheduling needs, use calendar specifications:Overlap Policies
When a schedule triggers while a previous run is still executing, the overlap policy determines what happens:Choosing an Overlap Policy
SKIP - Best for idempotent operations
SKIP - Best for idempotent operations
Use when it’s safe to miss a run. The next scheduled run will catch up.Example: Metrics collection, status checks
BUFFER_ONE - Ensure at least one catchup run
BUFFER_ONE - Ensure at least one catchup run
Use when you need to guarantee at least one run happens after a long-running execution.Example: Data synchronization
CANCEL_OTHER - Latest data wins
CANCEL_OTHER - Latest data wins
Use when only the most recent run matters and older runs should be cancelled.Example: Cache refresh
ALLOW_ALL - Parallel processing
ALLOW_ALL - Parallel processing
Use when runs are independent and can execute concurrently.Example: Processing independent queues
Managing Schedules
Pause and Resume
Temporarily stop a schedule without deleting it:Update Schedule
Modify an existing schedule’s configuration:Delete Schedule
Remove a schedule (soft delete - record is preserved for audit):List Schedules
Query existing schedules:Manual Trigger and Backfill
Manual Trigger
Execute a scheduled workflow immediately, outside of its normal schedule:- Testing the workflow
- Running on-demand when needed
- Recovering from issues
Backfill Missed Runs
If the scheduler was down and missed some runs, you can backfill them:Timezone Support
Schedules support timezone-aware execution:All schedule times are stored internally as UTC. The timezone is used to calculate the correct UTC time for each run.
Time Bounds
Limit when a schedule is active:Running the Scheduler
PyWorkflow supports two runtimes for schedule execution:- Local Runtime
- Celery Runtime (Distributed)
For development, testing, or single-process deployments, use the local scheduler:The local scheduler polls storage for due schedules and triggers workflows in-process.
- Poll storage for due schedules (every 5 seconds by default)
- Trigger workflow execution for due schedules
- Update
next_run_timeafter each run - Handle overlap policies automatically
The schedule primitives (
trigger_schedule, backfill_schedule, etc.) are runtime-agnostic
and will use whichever runtime is configured. You can switch between local and Celery
without changing your schedule management code.Activating Decorator-Based Schedules
When using@scheduled_workflow, the schedules need to be activated to create records in storage:
Complete Examples
Every-Minute Schedule with Celery (Distributed)
This example shows a workflow that runs every minute using Celery workers for distributed execution. 1. Define the scheduled workflow (myapp/workflows.py):
myapp/main.py):
minute_health_check every minute, and the Celery worker will execute it.
Every-Minute Schedule with Local Runtime
For testing or simple use cases, you can run schedules locally without Celery. 1. Define the workflow (local_schedule.py):
CLI Commands
Manage schedules from the command line:Best Practices
Use SKIP for most schedules
Use SKIP for most schedules
The
SKIP overlap policy is the safest default. It prevents resource exhaustion and ensures predictable behavior.Set appropriate intervals
Set appropriate intervals
Don’t schedule too frequently. Consider the typical workflow duration when setting intervals to avoid constant overlaps.
Handle failures gracefully
Handle failures gracefully
Scheduled workflows should handle transient failures with retries. Use step-level retries for resilience.
Monitor schedule health
Monitor schedule health
Track
successful_runs, failed_runs, and skipped_runs to identify issues with your schedules.Use idempotent operations
Use idempotent operations
Design scheduled workflows to be idempotent. They may run multiple times due to retries or backfills.
Consider timezones carefully
Consider timezones carefully
Be explicit about timezones, especially for schedules that should run at specific local times.
Schedule Status
Schedules can be in one of three states:Monitoring
Track schedule execution with built-in statistics:Next Steps
CLI Reference
Learn the full CLI commands for schedule management.
Workflows
Understand workflow concepts and patterns.
Fault Tolerance
Configure auto recovery for scheduled workflows.
Events
Track schedule events in the event log.