The schedule command manages scheduled jobs that run Goose recipes automatically at specified times.
Usage
goose schedule <subcommand> [OPTIONS]
goose sched <subcommand> [OPTIONS] # short alias
Subcommands
Add Scheduled Job
Add a new scheduled job.
goose schedule add --schedule-id <ID> --cron <EXPRESSION> --recipe-source <PATH>
Options:
Unique ID for the recurring scheduled job.Alias: --idExample: --schedule-id daily-report
Cron expression for when to run the job.Examples:
0 * * * * - Every hour at minute 0
0 9 * * * - Every day at 9:00 AM
0 0 * * 1 - Every Monday at midnight
@hourly - Every hour
@daily - Every day at midnight
Path to recipe file or base64 encoded recipe string.Example: --recipe-source ./recipes/daily-report.yaml
Examples:
# Hourly report
goose schedule add \
--schedule-id hourly-report \
--cron "0 * * * *" \
--recipe-source ./report.yaml
# Daily backup at 2 AM
goose schedule add \
--schedule-id daily-backup \
--cron "0 2 * * *" \
--recipe-source backup.yaml
# Weekly summary every Monday at 9 AM
goose schedule add \
--schedule-id weekly-summary \
--cron "0 9 * * 1" \
--recipe-source summary.yaml
Output:
✅ Using standard 5-field cron format: 0 * * * *
Scheduled job 'hourly-report' added. Recipe expected at ~/.config/goose/scheduled_recipes/hourly-report.yaml
List Scheduled Jobs
List all scheduled jobs.
Example output:
Scheduled Jobs:
- ID: daily-report
Status: ⏹️ IDLE
Cron: 0 9 * * *
Recipe Source (in store): daily-report.yaml
Last Run: 2025-03-04T09:00:00+00:00
- ID: hourly-backup
Status: 🟢 RUNNING
Cron: 0 * * * *
Recipe Source (in store): hourly-backup.yaml
Last Run: 2025-03-04T14:00:00+00:00
- ID: weekly-summary
Status: ⏸️ PAUSED
Cron: 0 9 * * 1
Recipe Source (in store): weekly-summary.yaml
Last Run: Never
Status indicators:
- 🟢
RUNNING - Currently executing
- ⏹️
IDLE - Waiting for next scheduled time
- ⏸️
PAUSED - Temporarily disabled
Remove Scheduled Job
Remove a scheduled job by ID.
goose schedule remove --schedule-id <ID>
Options:
ID of the scheduled job to remove.Alias: --id
Example:
goose schedule remove --schedule-id daily-report
Output:
Scheduled job 'daily-report' and its associated recipe removed.
List Schedule Sessions
List sessions created by a specific schedule.
goose schedule sessions --schedule-id <ID> [--limit <N>]
Options:
ID of the schedule.Alias: --id
Maximum number of sessions to return.Short: -l
Example:
goose schedule sessions --schedule-id daily-report --limit 10
Output:
Sessions for schedule ID 'daily-report':
- Session ID: 20250304_090000, Working Dir: /home/user, Description: "Daily Report", Schedule ID: daily-report
- Session ID: 20250303_090000, Working Dir: /home/user, Description: "Daily Report", Schedule ID: daily-report
Run Schedule Now
Trigger a scheduled job immediately.
goose schedule run-now --schedule-id <ID>
Options:
ID of the schedule to run.Alias: --id
Example:
goose schedule run-now --schedule-id daily-report
Output:
Successfully triggered schedule 'daily-report'. New session ID: 20250304_143022
Cron Expression Help
Show cron expression examples and help.
Output:
📅 Cron Expression Guide for goose Scheduler
===========================================
🕐 HOURLY SCHEDULES (Most Common Request):
0 * * * * - Every hour at minute 0 (e.g., 1:00, 2:00, 3:00...)
30 * * * * - Every hour at minute 30 (e.g., 1:30, 2:30, 3:30...)
0 */2 * * * - Every 2 hours at minute 0 (e.g., 2:00, 4:00, 6:00...)
@hourly - Every hour (same as "0 * * * *")
📅 DAILY SCHEDULES:
0 9 * * * - Every day at 9:00 AM
0 0 * * * - Every day at midnight
@daily - Every day at midnight
📆 WEEKLY SCHEDULES:
0 9 * * 1 - Every Monday at 9:00 AM
0 17 * * 5 - Every Friday at 5:00 PM
@weekly - Every Sunday at midnight
🗓️ MONTHLY SCHEDULES:
0 9 1 * * - First day of every month at 9:00 AM
@monthly - First day of every month at midnight
📝 CRON FORMAT:
┌─── minute (0 - 59)
│ ┌─── hour (0 - 23)
│ │ ┌─── day of month (1 - 31)
│ │ │ ┌─── month (1 - 12)
│ │ │ │ ┌─── day of week (0 - 7, Sunday = 0 or 7)
│ │ │ │ │
* * * * *
Services Status (Deprecated)
Check status of scheduler services.
goose schedule services-status
Output:
Service management has been removed as Temporal scheduler is no longer supported.
The built-in scheduler runs within the goose process and requires no external services.
Services Stop (Deprecated)
Stop scheduler services.
goose schedule services-stop
Output:
Service management has been removed as Temporal scheduler is no longer supported.
The built-in scheduler runs within the goose process and requires no external services.
Cron Expressions
Standard 5-field:
minute hour day month weekday
Extended 6-field (with seconds):
second minute hour day month weekday
Special Characters
Any value - matches all (e.g., * in hour = every hour)
Every nth interval (e.g., */5 in minute = every 5 minutes)
Range of values (e.g., 1-5 = 1,2,3,4,5)
List of values (e.g., 1,3,5 = 1 or 3 or 5)
Shorthand Expressions
Once a year - equivalent to 0 0 1 1 *Alias: @annually
Once a month - equivalent to 0 0 1 * *
Once a week - equivalent to 0 0 * * 0
Once a day - equivalent to 0 0 * * *Alias: @midnight
Once an hour - equivalent to 0 * * * *
Common Examples
Every 15 minutes:
Every hour at 30 minutes:
Every 2 hours:
Business hours (9 AM - 5 PM, weekdays):
First day of month:
Weekends only:
Recipe Storage
Scheduled recipes are stored in ~/.config/goose/scheduled_recipes/:
~/.config/goose/scheduled_recipes/
├── daily-report.yaml
├── hourly-backup.yaml
└── weekly-summary.yaml
When you add a schedule, the recipe is copied to this directory.
Session Tracking
Each scheduled execution creates a session:
Session metadata includes:
schedule_id - Links to the schedule
working_dir - Execution directory
name - Session description
- Creation timestamp
View scheduled sessions:
goose schedule sessions --schedule-id daily-report
goose session list # All sessions (includes scheduled)
Error Handling
Invalid cron expression:
⚠️ Unusual cron format detected: '* * *'
Common formats:
- 5 fields: '0 * * * *'
Job already exists:
Error: Job with ID 'daily-report' already exists.
Job not found:
Error: Job with ID 'unknown-job' not found.
Recipe validation error:
Error with recipe source: Recipe validation failed. Path: ./invalid.yaml
Examples
Hourly data sync:
goose schedule add \
--schedule-id hourly-sync \
--cron "0 * * * *" \
--recipe-source ./recipes/sync-data.yaml
Daily report at 9 AM:
goose schedule add \
--schedule-id daily-report \
--cron "0 9 * * *" \
--recipe-source ./recipes/generate-report.yaml
Weekly cleanup on Sundays:
goose schedule add \
--schedule-id weekly-cleanup \
--cron "0 0 * * 0" \
--recipe-source ./recipes/cleanup.yaml
Test schedule immediately:
# Add schedule
goose schedule add --schedule-id test-job --cron "@hourly" --recipe-source test.yaml
# Run now to test
goose schedule run-now --schedule-id test-job
# Check sessions
goose schedule sessions --schedule-id test-job
Remove old schedule:
goose schedule remove --schedule-id old-job
Built-in Scheduler
Goose includes a built-in scheduler:
- No external services required
- Runs within Goose process
- Persistent across restarts
- Automatic session creation
- Error logging and recovery
Storage:
- Schedules:
~/.config/goose/scheduler.json
- Recipes:
~/.config/goose/scheduled_recipes/
- Sessions:
~/.config/goose/sessions/
See Also