Scheduling
Configure time-based workflow execution with cron expressions, timezone handling, and recurring schedules.
Schedule Configuration
Schedule triggers use cron expressions to define when workflows execute:
{
"type": "schedule",
"config": {
"cron": "0 9 * * 1-5",
"timezone": "America/New_York",
"skip_if_running": true,
"max_active_runs": 1
}
}Configuration fields:
- cron - Cron expression defining execution schedule (required)
- timezone - IANA timezone name (default: UTC)
- skip_if_running - Skip execution if previous run is still active (default: true)
- max_active_runs - Maximum concurrent runs (default: 1)
Cron Expressions
Syntax
Cron format: minute hour day month weekday
┌───────────── minute (0 - 59)
│ ┌─────────── hour (0 - 23)
│ │ ┌───────── day of month (1 - 31)
│ │ │ ┌─────── month (1 - 12)
│ │ │ │ ┌───── day of week (0 - 6, Sunday = 0)
│ │ │ │ │
* * * * *Special characters:
| Character | Meaning | Example |
|---|---|---|
* | Any value | * * * * * = every minute |
, | List separator | 0 9,17 * * * = 9 AM and 5 PM |
- | Range | 0 9-17 * * * = every hour from 9 AM to 5 PM |
/ | Step | */15 * * * * = every 15 minutes |
? | No specific value | Use in day or weekday when using the other |
Examples by Frequency
Minutes
# Every minute
* * * * *
# Every 5 minutes
*/5 * * * *
# Every 15 minutes
*/15 * * * *
# Every 30 minutes
*/30 * * * *
# At minute 30 of every hour
30 * * * *
# Every 10 minutes during business hours (9-5)
*/10 9-17 * * *Business Schedules
Common patterns for business workflows:
# Daily report at 9 AM (weekdays)
0 9 * * 1-5
# Nightly batch processing at 2 AM
0 2 * * *
# Weekly summary every Friday at 5 PM
0 17 * * 5
# Monthly report on first day of month
0 8 1 * *
# Quarterly review (first Monday of Jan, Apr, Jul, Oct)
0 9 1-7 1,4,7,10 1
# Hourly during market hours (9:30 AM - 4 PM EST, weekdays)
30 9-16 * * 1-5Data Processing Schedules
# Every 5 minutes (real-time processing)
*/5 * * * *
# Every 15 minutes during business hours
*/15 9-17 * * 1-5
# Hourly incremental sync
0 * * * *
# Nightly full sync at 1 AM
0 1 * * *
# Weekly backup every Sunday at midnight
0 0 * * 0
# Daily cleanup at 4 AM
0 4 * * *Timezone Handling
IANA Timezones
Always specify timezone explicitly to avoid ambiguity:
{
"cron": "0 9 * * *",
"timezone": "America/New_York"
}This schedule runs at 9 AM Eastern Time, automatically adjusting for daylight saving time.
Common timezones:
| Region | Timezone |
|---|---|
| US Eastern | America/New_York |
| US Central | America/Chicago |
| US Mountain | America/Denver |
| US Pacific | America/Los_Angeles |
| UK | Europe/London |
| Central Europe | Europe/Paris |
| India | Asia/Kolkata |
| Japan | Asia/Tokyo |
| Australia (Sydney) | Australia/Sydney |
Full list: IANA Time Zone Database
Daylight Saving Time
Cron expressions respect DST transitions:
Spring Forward (March):
- Schedule:
0 2 * * *(2 AM daily) - DST transition: Clocks jump from 2:00 AM → 3:00 AM
- Behavior: Schedule skips on transition day (no 2 AM exists)
Fall Back (November):
- Schedule:
0 1 * * *(1 AM daily) - DST transition: Clocks fall back from 2:00 AM → 1:00 AM
- Behavior: Schedule runs once (first 1 AM occurrence)
Avoid scheduling critical workflows at 2:00-2:59 AM in timezones with DST. These times may be skipped (spring) or duplicated (fall). Use 3:00 AM or later for safety.
UTC vs Local Time
Use UTC when:
- Coordinating across multiple timezones
- Server infrastructure in one timezone, users in another
- Avoiding DST complexity
- Consistency is more important than “local time”
Use local timezone when:
- User-facing notifications (send at 9 AM user’s time)
- Business hours workflows (weekdays 9-5 in office timezone)
- Regulatory requirements (end-of-day in local timezone)
Example: Multi-region scheduling
Send daily reports at 9 AM local time in each region:
// US East
{"cron": "0 9 * * *", "timezone": "America/New_York"}
// US West
{"cron": "0 9 * * *", "timezone": "America/Los_Angeles"}
// Europe
{"cron": "0 9 * * *", "timezone": "Europe/London"}Create separate schedules for each region rather than one UTC schedule.
Concurrent Runs
Skip if Running
Prevent overlapping executions with skip_if_running:
{
"cron": "*/5 * * * *",
"skip_if_running": true
}Behavior:
- Schedule fires every 5 minutes
- If previous run is still executing, skip this execution
- Next attempt is 5 minutes later
Use when:
- Long-running workflows (may exceed schedule interval)
- Resource-intensive processing (avoid overload)
- Idempotency is hard to achieve
Max Active Runs
Limit concurrent executions:
{
"cron": "*/1 * * * *",
"max_active_runs": 3
}Behavior:
- Allow up to 3 concurrent runs
- If 3 runs are active, queue new executions
- Queued runs start when a slot frees up
Use when:
- Processing throughput is bounded
- Preventing system overload
- Rate limiting external API calls
Queue vs Skip
Choose based on whether missed executions matter:
| Scenario | Configuration | Behavior |
|---|---|---|
| Must process every trigger | max_active_runs: 3 | Queue executions |
| Only care about latest | skip_if_running: true | Skip queued executions |
| Real-time processing | max_active_runs: 10 | Allow many concurrent runs |
Tick Timeline
The tick timeline shows scheduled evaluations:
- Green ticks - Workflow triggered successfully
- Gray ticks - Skipped (previous run still active)
- Red ticks - Failed (error during trigger)
- White gaps - Sensor paused or inactive
Tick details:
Hover over any tick to see:
- Scheduled time vs actual execution time
- Skip reason (if skipped)
- Triggered run ID (if successful)
- Error message (if failed)
Monitoring schedule health:
- Regular green ticks - Schedule running normally
- Frequent gray ticks - Runs taking longer than interval (increase interval or enable queuing)
- Red ticks - Configuration error or workflow startup failure
- Irregular gaps - Sensor was paused or system downtime
Testing Schedules
Validate Cron Expressions
Use online validators to verify cron syntax:
- crontab.guru - Interactive cron expression builder
- crontab.cronhub.io - Expression validator
Example:
- Input:
0 9 * * 1-5 - Output: “At 09:00 on every day-of-week from Monday through Friday.”
Manual Trigger
Test schedule without waiting for next tick:
- Navigate to Automation page
- Select schedule sensor
- Click “Test Trigger”
- Sensor evaluates immediately, triggering workflow
This verifies:
- Workflow exists and is accessible
- Workflow input is constructed correctly
- Permissions are valid
Dry Run Mode
Preview next scheduled execution:
{
"cron": "0 9 * * 1-5",
"timezone": "America/New_York",
"dry_run": true
}Dry run calculates next execution time without triggering workflow. Use to verify:
- Cron expression produces expected schedule
- Timezone adjustment is correct
- DST transitions are handled properly
Common Patterns
Staggered Schedules
Distribute load by staggering execution times:
# Process tenant A at 1 AM
0 1 * * *
# Process tenant B at 2 AM
0 2 * * *
# Process tenant C at 3 AM
0 3 * * *Or use minute offsets:
# Tenant A
0 1 * * *
# Tenant B (5 min later)
5 1 * * *
# Tenant C (10 min later)
10 1 * * *Progressive Intervals
Increase interval during low-activity periods:
# Every 5 minutes during business hours (9 AM - 5 PM)
*/5 9-17 * * 1-5
# Every 30 minutes during evening (5 PM - 11 PM)
*/30 17-23 * * 1-5
# Hourly overnight (11 PM - 9 AM)
0 23-8 * * 1-5
# Every 2 hours on weekends
0 */2 * * 0,6This optimizes resource usage based on expected traffic.
Conditional Execution
Combine schedules with workflow logic:
# In workflow START node
import datetime
# Skip on holidays
holidays = ['2024-12-25', '2024-07-04']
today = datetime.date.today().isoformat()
if today in holidays:
exit() # Exit workflow without processingOr use multiple schedules:
# Regular schedule (every weekday)
0 9 * * 1-5
# Special schedule (first Monday of month only)
0 9 1-7 * 1Monitoring and Alerts
Metrics to Track
- Execution count - Total runs triggered by schedule
- Skip rate - Percentage of skipped executions
- Failure rate - Failed triggers vs successful
- Latency - Time between scheduled tick and actual execution start
Alert Conditions
Set up alerts for:
Missed executions:
- No successful tick in expected time window
- Example: Daily schedule should fire once per day
High skip rate:
- More than 20% of ticks skipped
- Indicates runs are taking too long
Consecutive failures:
- 3+ failed ticks in a row
- Suggests configuration or infrastructure issue
Execution drift:
- Actual execution time consistently late (> 5 minutes after scheduled)
- Indicates system overload or resource contention
Dashboard Monitoring
The Automation page shows:
- Next scheduled run - Countdown to next execution
- Last successful run - Timestamp and run ID
- Tick history - Visual timeline (last 100 ticks)
- Error rate - Failures in last 24 hours
Best Practices
Schedule Design
- Choose appropriate intervals - Don’t poll more frequently than needed
- Respect DST - Avoid 2:00-2:59 AM in DST timezones
- Stagger loads - Distribute heavy processing across time
- Test thoroughly - Validate cron expressions before deployment
Performance
- Batch when possible - Process multiple items per run
- Skip if running - Prevent queue buildup for long workflows
- Monitor execution time - If exceeding interval, increase interval or optimize workflow
Reliability
- Idempotent workflows - Safe to run multiple times with same input
- Error handling - Gracefully handle missing data or API failures
- Retry logic - Automatically retry transient failures
- Alerting - Get notified of schedule failures
Security
- Least privilege - Scheduled workflows should have minimal permissions
- Audit logging - Track all scheduled executions
- Secret rotation - Update API keys used by scheduled workflows
- Review regularly - Disable unused schedules
Troubleshooting
Schedule Not Firing
Check:
- Sensor status is “Active” (not paused/inactive)
- Cron expression is valid (use crontab.guru)
- Timezone is correct
- Next scheduled tick is in the future
Common issues:
- Sensor paused or disabled
- Invalid cron syntax (e.g.,
60 * * * *- minute 60 doesn’t exist) - Timezone mismatch (schedule runs in different timezone than expected)
Executions Skipped
Reasons:
skip_if_running: trueand previous run still activemax_active_runslimit reached- System overload (scheduler backed up)
Solutions:
- Increase schedule interval (give workflows more time to complete)
- Enable queueing (
max_active_runs > 1) - Optimize workflow performance
- Scale infrastructure (more workers)
Inconsistent Timing
Symptoms:
- Schedule fires at irregular times
- Executions drift later over time
- Missed ticks during high load
Solutions:
- Check system load (CPU, memory)
- Scale scheduler infrastructure
- Reduce concurrent workflows
- Stagger schedules to distribute load
Next Steps
- Configure trigger types for event-driven execution
- Set up webhooks for external integrations
- Monitor schedule health in the Automation dashboard
- Optimize workflow performance for faster execution