Skip to main content

Overview

Cron jobs are scheduled tasks that run at specified times. They can either send prompts to agents or execute deterministic shell commands directly. They support three schedule types: standard cron expressions, fixed intervals, and one-shot datetimes. The daemon manages all timers and executes jobs automatically.

Schedule Types

Cron Expressions

Standard five-field cron syntax for precise recurring schedules.
Create a cron-based job with --cron:
Common expressions:

Intervals

Fixed-duration intervals using a compact duration syntax. Supported units: s (seconds), m (minutes), h (hours), d (days).
Duration examples:

One-Shot Datetime

Run a job exactly once at a specific ISO 8601 datetime. Accepts formats like 2025-02-01T15:00, 2025-02-01T15:00:00Z, or 2025-02-01T15:00:00-03:00.
One-shot jobs are automatically deleted after execution. The --delete-after flag is optional here since --at jobs are deleted by default, but it makes the intent explicit.

Timezone Handling

Cron expressions are evaluated in a specific timezone. Use --tz to set it:
If --tz is omitted, the default timezone from ravi settings is used (configured via ravi settings set defaultTimezone America/Sao_Paulo).
The --tz flag only applies to cron expressions. Interval and one-shot schedules are timezone-independent.
You can change the timezone of an existing job:

Session Targets

Agent jobs run in one of two session modes:

Main Session (default)

The job prompt is sent to the agent’s shared main session, the same session used by WhatsApp, Telegram, and CLI interactions. Responses are delivered to the channel the job was created from.

Isolated Session

Each job gets its own dedicated session (agent:{agentId}:cron:{jobId}), completely separate from the main conversation. Useful for background tasks that should not mix with user conversations.
In isolated sessions, the agent can use cross_send to deliver results to a specific channel or user when needed.

Prompt Format

When a cron job fires, the agent receives the message prefixed with a header that includes the job name and current timestamp:
This prefix helps the agent understand the context of the prompt — that it originated from a scheduled job rather than a user message.

Shell Jobs

Use --shell or --exec for deterministic scripts that do not need agent reasoning. Shell jobs are tracked by ravi cron list/show/run like agent jobs, but successful runs do not publish any prompt and do not spend LLM tokens.
On failure, a shell job records lastStatus=error, lastError, duration, and exit code. To involve an agent only when the command fails, add an explicit error action:
Optional shell controls:
--timeout accepts seconds as a bare number or duration strings like 30s, 5m, or 1h. --env-file reads simple dotenv-style KEY=value lines and merges them into the shell process environment.

Anti-Drift

For interval-based jobs, the next run time is calculated from the originally scheduled time, not from when execution finishes. This prevents timing drift caused by variable execution durations. For example, with a --every 30m job scheduled at 09:00:
  • If execution takes 2 minutes (finishes at 09:02), the next run is still 09:30
  • If execution takes 10 minutes (finishes at 09:10), the next run is still 09:30
For cron expressions, the next occurrence is calculated using the croner library with full timezone support.

Job Properties

Each cron job has the following properties: State fields (read-only, visible in ravi cron show):

CLI Workflows

Creating Jobs

Listing and Inspecting

Enabling and Disabling

When a job is re-enabled, its nextRunAt is recalculated from the current time so it does not immediately fire for all missed runs.

Updating Properties

Manual Execution

Run a job immediately, ignoring its schedule:
This sends a trigger signal to the daemon. The job executes with the same prompt and session as a normal scheduled run. The schedule is not affected.

Deleting Jobs

Practical Examples

Daily standup report (weekdays at 9am)

Periodic health check (every 2 hours)

One-time reminder

Weekly metrics every Monday morning

Email check every 15 minutes during business hours

Troubleshooting

Job not firing

  1. Check if enabled: ravi cron show <id> — verify Enabled: yes
  2. Check next run time: The Next run field shows when the job is scheduled to fire next
  3. Daemon running: ravi daemon status — the daemon must be running to execute jobs
  4. Check logs: ravi daemon logs -f — look for cron:runner entries
  5. Manual test: ravi cron run <id> — triggers immediately to verify the job works

Timing seems off

  • Verify the timezone: ravi cron show <id> displays the schedule including timezone
  • For cron expressions without --tz, the system default timezone is used. Check with ravi settings list
  • Interval jobs use anti-drift: if a job was disabled and re-enabled, nextRunAt resets to “now + interval”

Job runs but no response appears

  • Main session: The response routes to the channel the job was created from. If the job was created from CLI, responses go to the agent’s main session
  • Isolated session: The agent must use cross_send to deliver results to a channel. Without it, the response stays in the isolated session
  • Check agent logs: ravi daemon logs -f | grep cron

One-shot job shows “(expired)”

One-shot jobs (--at) whose datetime has passed show (expired) in the list. They will not fire again. If the job has delete-after enabled (the default for --at), it is automatically deleted after execution.