Skip to main content
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:
--schedule-id
string
required
Unique ID for the recurring scheduled job.Alias: --idExample: --schedule-id daily-report
--cron
string
required
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
--recipe-source
string
required
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.
goose schedule list
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:
--schedule-id
string
required
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:
--schedule-id
string
required
ID of the schedule.Alias: --id
--limit
number
default:"50"
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:
--schedule-id
string
required
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.
goose schedule cron-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

Format

Standard 5-field:
minute hour day month weekday
Extended 6-field (with seconds):
second minute hour day month weekday

Special Characters

*
char
Any value - matches all (e.g., * in hour = every hour)
*/n
pattern
Every nth interval (e.g., */5 in minute = every 5 minutes)
n-m
range
Range of values (e.g., 1-5 = 1,2,3,4,5)
n,m
list
List of values (e.g., 1,3,5 = 1 or 3 or 5)

Shorthand Expressions

@yearly
shorthand
Once a year - equivalent to 0 0 1 1 *Alias: @annually
@monthly
shorthand
Once a month - equivalent to 0 0 1 * *
@weekly
shorthand
Once a week - equivalent to 0 0 * * 0
@daily
shorthand
Once a day - equivalent to 0 0 * * *Alias: @midnight
@hourly
shorthand
Once an hour - equivalent to 0 * * * *

Common Examples

Every 15 minutes:
--cron "*/15 * * * *"
Every hour at 30 minutes:
--cron "30 * * * *"
Every 2 hours:
--cron "0 */2 * * *"
Business hours (9 AM - 5 PM, weekdays):
--cron "0 9-17 * * 1-5"
First day of month:
--cron "0 0 1 * *"
Weekends only:
--cron "0 10 * * 0,6"

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

Build docs developers (and LLMs) love