Scheduled Execution
Schedule commands and playbooks to run automatically.
Nefia includes a built-in cron scheduler that automates recurring tasks -- backups, log rotation, health checks, compliance scans -- across your fleet. Schedules are defined and managed through the CLI and executed by the Nefia daemon process. Schedule state syncs with the web dashboard so your team has visibility into upcoming and past runs.
Creating a Schedule
Use nefia schedule create to define a recurring playbook run:
nefia schedule create \
--name daily-backup \
--cron "0 2 * * *" \
--playbook backup \
--target allFour flags are required: --name, --cron, --playbook, and --target. The --target flag accepts the same host selectors used elsewhere (all, host:<name>, group:<name>, tag:<name>, etc.).
After creation, the CLI prints the schedule ID and the next 3 upcoming run times:
Schedule "daily-backup" created (ID: sched_a1b2c3d4) Cron: 0 2 * * * (Every day at 02:00) Next 3 runs: 2026-03-05 02:00:00 UTC 2026-03-06 02:00:00 UTC 2026-03-07 02:00:00 UTC
Optional Flags
| Flag | Description |
|---|---|
--var key=value | Pass template variables to the playbook (repeatable) |
--timezone | IANA timezone for the cron expression (default: local) |
--overlap-policy | Behavior when the previous run is still executing (see below) |
--missed-run-policy | Behavior when the daemon was offline during a scheduled window (see below) |
--description | Human-readable description of the schedule |
Example with all optional flags:
nefia schedule create \
--name web-health \
--cron "*/5 * * * *" \
--playbook health-check \
--target group:webservers \
--timezone "America/New_York" \
--var retention_days=30 \
--var alert_threshold=5 \
--overlap-policy skip \
--missed-run-policy run_once \
--description "Check web server health every 5 minutes"Managing Schedules
List All Schedules
nefia schedule listThe list command also shows whether the daemon is currently running:
Daemon: running (PID 48201)
NAME CRON PLAYBOOK TARGET STATUS LAST RUN
daily-backup 0 2 * * * backup all enabled 2h ago OK web-health */5 * * * * health-check group:web enabled 3m ago OK rotate-logs 0 0 * * 0 log-rotate all enabled 2d ago OK old-cleanup 0 3 1 * * cleanup tag:staging disabled 14d ago FAIL
If the daemon is not running, the output warns you:
Daemon: not running Start with: nefia daemon
NAME CRON PLAYBOOK TARGET STATUS LAST RUN ...
Show Schedule Details
nefia schedule show daily-backupDisplays the full schedule definition, including cron description, variables, policies, last run status, and the next 5 upcoming runs:
Name: daily-backup ID: sched_a1b2c3d4 Description: Nightly backup of all hosts Cron: 0 2 * * * (Every day at 02:00) Playbook: backup Target: all Enabled: true Overlap: skip Missed Run: run_once Created By: admin Created At: 2026-02-20T10:30:00Z Variables: retention_days = 30
Last Run: 2026-03-04T02:00:12Z (success)
Next 5 runs: 2026-03-05 02:00:00 UTC 2026-03-06 02:00:00 UTC 2026-03-07 02:00:00 UTC 2026-03-08 02:00:00 UTC 2026-03-09 02:00:00 UTC
You can reference schedules by name or ID in all subcommands.
Update a Schedule
nefia schedule update daily-backup --cron "30 1 * * *"
nefia schedule update daily-backup --playbook backup-v2 --target group:production
nefia schedule update daily-backup --timezone "Asia/Tokyo" --description "Updated backup"
nefia schedule update daily-backup --overlap-policy skip --missed-run-policy run_onceOnly the flags you pass are changed; everything else is preserved. The following flags are available:
| Flag | Description |
|---|---|
--cron | Update the cron expression |
--playbook | Change the playbook |
--target | Change the target selector |
--timezone | Change the IANA timezone |
--description | Update the description |
--overlap-policy | Change the overlap policy (skip, allow, cancel_running) |
--missed-run-policy | Change the missed run policy (skip, run_once) |
--enabled | Enable or disable the schedule (true / false) |
Enable and Disable
nefia schedule disable daily-backup # Temporarily pause
nefia schedule enable daily-backup # ResumeDisabled schedules are skipped by the daemon but remain in the schedule list.
Delete a Schedule
nefia schedule delete daily-backupPrompts for confirmation unless --yes is passed. Deletion is permanent and removes the schedule definition and its state.
Execution History
View past runs for a specific schedule:
nefia schedule history daily-backupSTARTED SCHEDULE TRIGGER STATUS DURATION HOSTS
2026-03-04 02:00:01 daily-backup cron success 3m 12s 4/4 2026-03-03 02:00:00 daily-backup cron success 3m 08s 4/4 2026-03-02 14:30:10 daily-backup manual success 3m 45s 4/4 2026-03-01 02:00:00 daily-backup cron partial_failure 4m 02s 3/4
View history across all schedules:
nefia schedule historyLimit the number of records:
nefia schedule history daily-backup --limit 5The default limit is 20 records.
Manual Trigger
Trigger a schedule immediately without waiting for the next cron window:
nefia schedule trigger daily-backupThis runs the playbook with the same target and variables as the schedule definition. The schedule does not need to be enabled. Manual triggers execute the playbook directly and do not require the daemon to be running.
The run is recorded in the history with trigger: manual.
Overlap and Missed-Run Policies
Overlap Policy
Controls what happens when a new cron window fires while the previous execution is still running.
| Policy | Behavior |
|---|---|
skip (default) | Skip the new run if the previous is still executing |
allow | Allow the new run to start concurrently (up to 3 concurrent executions per schedule) |
cancel_running | Cancel the running execution and start the new one |
Missed-Run Policy
Controls what happens when the daemon comes back online after missing one or more scheduled windows.
| Policy | Behavior |
|---|---|
skip (default) | Ignore missed runs entirely |
run_once | Execute the playbook once as a catch-up when the daemon starts |
Set policies at creation time:
nefia schedule create \
--name critical-backup \
--cron "0 */6 * * *" \
--playbook backup \
--target all \
--overlap-policy cancel_running \
--missed-run-policy run_onceOr update them later:
nefia schedule update critical-backup --overlap-policy skip --missed-run-policy skipRunning the Daemon
Schedules require the Nefia daemon to be running. In addition to the cron scheduler, the daemon manages several background subsystems:
| Subsystem | Description |
|---|---|
| Cron scheduler | Evaluates schedule definitions and triggers playbook runs at the configured times |
| VPN monitoring | Watches tunnel health and reconnects dropped peers |
| Host sync | Periodically syncs host state to the web dashboard (when authenticated) |
| Idle sweep | Closes idle SSH/SFTP connections to free resources |
| Key rotation | Schedules periodic rotation of VPN and agent keys |
| Config hot-reload | Watches nefia.yaml for changes and applies them without restart (30-second poll) |
Start in Foreground
nefia daemonOr equivalently:
nefia daemon runNefia daemon started PID: 48201 Schedules: 3 active Next run: daily-backup at 2026-03-05 02:00 UTC
The daemon runs until interrupted (Ctrl+C / SIGTERM). It acquires an exclusive PID lock to prevent multiple instances.
Install as a System Service
For persistent operation, generate a platform-specific service configuration with nefia daemon install. The output is printed to stdout so you can redirect it to the appropriate location.
nefia daemon install > ~/Library/LaunchAgents/ai.nefia.daemon.plist
launchctl load ~/Library/LaunchAgents/ai.nefia.daemon.plistThis creates a launchd plist with RunAtLoad and KeepAlive enabled. Logs go to /tmp/nefia-daemon.log.
Graceful Shutdown
When the daemon receives a shutdown signal, it:
- Stops accepting new schedule executions
- Cancels all running executions
- Waits up to 60 seconds for in-flight executions to complete
- Persists final schedule state to disk
Crash Recovery
If the daemon crashes while an execution is in progress, it records the crashed execution as cancelled with the message "daemon crashed during execution" on the next startup. This ensures the execution history remains accurate.
Web Dashboard Sync
When authenticated (via nefia login), the daemon periodically syncs schedule definitions and execution history to the web dashboard. This gives your team visibility into schedules without needing CLI access.
The sync interval is controlled by the sync_interval_sec configuration option (default: 300 seconds / 5 minutes). The sync endpoint is POST /api/schedules/sync and uses the same authentication as other API calls.
The sync is one-directional: CLI to dashboard. Schedules are always created and managed through the CLI.
Configuration
Schedule settings in nefia.yaml:
schedule:
enabled: true
sync_interval_sec: 300
retention_days: 90
max_concurrent_schedules: 5| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Enable or disable the scheduler. When false, the daemon starts but skips all schedule processing. |
sync_interval_sec | int | 300 | How often (in seconds) the daemon syncs schedule state to the web dashboard. |
retention_days | int | 90 | Days to retain execution history. Old records are cleaned up daily. |
max_concurrent_schedules | int | 5 | Maximum number of schedules executing in parallel across all schedules. |
JSON Output
All schedule commands support --output json for scripting and automation:
nefia schedule list --output json
nefia schedule show daily-backup --output json
nefia schedule history daily-backup --output jsonQuick Reference
| Command | Description |
|---|---|
nefia schedule create | Create a new schedule (requires --name, --cron, --playbook, --target) |
nefia schedule list | List all schedules with status and last run |
nefia schedule show <name> | Show full details for a schedule |
nefia schedule update <name> | Modify schedule properties |
nefia schedule delete <name> | Permanently remove a schedule |
nefia schedule enable <name> | Resume a paused schedule |
nefia schedule disable <name> | Pause a schedule without deleting it |
nefia schedule history [name] | Show execution history (optionally filtered by schedule) |
nefia schedule trigger <name> | Run a schedule immediately (does not require daemon) |
nefia daemon | Start the daemon in the foreground |
nefia daemon run | Same as nefia daemon |
nefia daemon install | Generate platform-specific service configuration |
MCP Tools
All schedule operations are available via MCP for AI agent orchestration:
| Tool | Description |
|---|---|
nefia.schedule.list | List all configured schedules. |
nefia.schedule.show | Show details of a specific schedule. |
nefia.schedule.create | Create a new cron-based schedule. |
nefia.schedule.update | Update schedule configuration. |
nefia.schedule.delete | Delete a schedule. |
nefia.schedule.enable | Enable a disabled schedule. |
nefia.schedule.disable | Disable a schedule without deleting it. |
nefia.schedule.history | View execution history for a schedule. |
nefia.schedule.trigger | Manually trigger a schedule for immediate execution. |
Related
Full reference for all Nefia CLI commands and flags.
Back up your configuration, state, and audit logs.
Share schedules and hosts across your team.