Skip to content

Cron schedules

Bestie can run scheduled tasks without tying them to a chat channel. Use cron schedules for precise reminders, recurring checks, and background automations that should happen on a timetable.

Cron schedules are stored in Bestie’s local SQLite memory store. The scheduler runs each due job as an isolated Bestie chat turn using the prompt saved with that schedule.

Use cron schedules when a task needs predictable timing:

  • Daily or weekly check-ins.
  • Timed reminders.
  • Recurring project, inbox, or system checks.
  • Background agent turns that should run independently from Telegram, CLI, or web sessions.

For conversational follow-ups that depend on recent chat context, a normal channel interaction may still be a better fit.

Every morning at 09:00, summarize today's priorities.
Every weekday at 18:00, check whether open tasks need follow-up.
Every 30 minutes, run a lightweight health check.
At a specific time, send a reminder back into the configured channel.

Bestie supports three schedule types:

Type Value Use it for
interval 30s, 5m, 1h, 2d Repeating jobs based on elapsed time.
cron_expr 0 8 * * * Calendar-style schedules using five cron fields.
once 2026-12-25T08:00:00Z One-time jobs at a future ISO timestamp.

Intervals must be positive and no longer than 365 days. Cron expressions use five fields: minute, hour, day of month, month, and day of week. Bestie evaluates cron expressions in UTC.

Create a schedule interactively:

Terminal window
bestie cron add

Or provide the values directly:

Terminal window
bestie cron add \
--name daily-priority-check \
--type cron_expr \
--schedule "0 9 * * *" \
--prompt "Summarize today's priorities from memory and active projects."

Bestie validates the schedule before saving it. A valid schedule prints the new schedule ID, schedule value, next run time, and prompt.

Use --channel to send job results to a specific destination:

Terminal window
bestie cron add \
--name morning-check-in \
--type cron_expr \
--schedule "0 8 * * *" \
--channel telegram:123456789 \
--prompt "Send a concise morning check-in."

Channel destinations must use one of these formats:

telegram:<userId>
zalo:<userId>

Telegram cron notifications require a numeric chat id. If Telegram is configured with a username instead of a numeric id, Bestie skips the cron notification and writes the reason to logs.

When no schedule-specific channel is set, Bestie tries the configured Telegram owner and Zalo owner destinations if those channels are enabled and have tokens available.

Terminal window
bestie cron list

The list output shows each schedule’s ID, name, schedule type and value, channel, next run time, and status.

Use the ID for logs, toggles, and removal.

Run the scheduler in the foreground:

Terminal window
bestie cron run

The scheduler starts immediately, checks for due jobs every 30 seconds, and stops when it receives Ctrl+C, SIGINT, or SIGTERM.

For a long-lived background process, run cron through Bestie’s daemon manager:

Terminal window
bestie daemon start --channel cron
bestie daemon status --channel cron

See Run Bestie in the background for daemon start, restart, stop, and systemd service behavior.

Show recent cron logs for all schedules:

Terminal window
bestie cron logs

Show logs for one schedule:

Terminal window
bestie cron logs 3

Each run stores an OK or ERR result. Successful output is truncated before it is stored in the cron log.

Turn a schedule off or back on:

Terminal window
bestie cron toggle 3

Remove a schedule:

Terminal window
bestie cron remove 3

bestie cron rm 3 is also accepted.

Telegram and Zalo channel chats support a small /cron management surface for schedules attached to that same channel destination.

Inside the channel, use:

/cron list
/cron delete <id>

/cron remove <id> is also accepted. Channel commands only list or delete schedules whose destination matches the current channel and user id.

Cron jobs should follow the same approval model as the rest of Bestie:

  • Read-only checks can run automatically when configured.
  • External actions such as sending messages, posting publicly, spending money, or changing account settings should still require approval unless the owner explicitly configured otherwise.
  • Scheduled jobs should be narrow and auditable so the owner can understand what ran and why.

Cron prompts are stored locally and run later without another interactive confirmation. Do not put secrets, raw tokens, or private keys in the prompt. If a job should perform a risky action, schedule a review or summary step and keep the final action behind approval.

Keep scheduled tasks small and specific:

name: daily-priority-check
schedule: 0 9 * * *
action: ask the agent to summarize today's priorities from memory and active projects

For higher-risk workflows, schedule the review step only and ask for approval before taking action.

Check the schedule type and value:

Terminal window
bestie cron add --type interval --schedule 30m --prompt "Check project status."
bestie cron add --type cron_expr --schedule "0 8 * * *" --prompt "Run the morning check-in."
bestie cron add --type once --schedule "2026-12-25T08:00:00Z" --prompt "Send the reminder."

once timestamps must be in the future. interval values must use s, m, h, or d.

Confirm the scheduler is running:

Terminal window
bestie daemon status --channel cron

If it is stopped, start it:

Terminal window
bestie daemon start --channel cron

Then check whether the schedule is enabled and has a next run time:

Terminal window
bestie cron list

Check the destination format and channel setup:

Terminal window
bestie channels doctor --channel telegram --connect
bestie channels doctor --channel zalo --connect
bestie cron logs

For Telegram, use a numeric chat id in telegram:<userId> destinations.