Scheduled tasks reference

Hermes Agent Cron & Scheduled Tasks

Hermes cron runs an agent prompt (or a plain script) on a schedule, and it only fires while a Hermes process with a scheduler is running — the messaging gateway, which checks for due jobs every 60 seconds, or the Hermes Desktop app's backend. A job definition on disk does nothing by itself: an ordinary hermes chat session does not fire jobs, and nothing fires while your computer is asleep or off.

Create jobs in plain language (“every weekday at 9am, summarize my inbox and send it to Telegram”), with /cron add in chat, or with hermes cron create. Check that the scheduler is alive with hermes cron status. Bot Mode routines are the same cron jobs with a bot's name on them.

Checked against official Nous Research sources on September 26, 2026 (Hermes Agent v0.21.5).

What has to be running for jobs to fire

What is runningDo scheduled jobs fire?Notes
hermes gateway (foreground or installed service)YesThe gateway ticks the scheduler every 60 seconds and runs due jobs in fresh agent sessions.
Hermes Desktop app, openYesThe Desktop's primary backend runs its own ticker for every local profile's jobs, even while an idle profile's backend is asleep.
A hermes CLI or TUI chat onlyNoThe official cron troubleshooting guide says a regular chat session does not fire jobs. hermes cron tick runs one tick by hand.
Nothing (computer asleep, off, or Hermes quit)NoWhen a scheduler comes back, each recurring job that missed a slot runs once, not once per missed slot.
Hermes Cloud and other hosted deploymentsYes, while the agent is runningA hosted scheduler hands each fire to the gateway; a failed hand-off is recorded as last_fire_error.

So the practical question is not “did I create the job?” but “will a gateway or the Desktop app be running on that machine at the scheduled time?” On a laptop, a 7am job fires at 7am only if the laptop is awake with Hermes running; otherwise it runs once when Hermes next starts. Set cron.catch_up_missed: false to skip missed slots instead.

Our inference: The docs say the Desktop backend ticks cron while the app runs. We found no statement that it keeps ticking after you quit the app, so this page assumes it does not. If you need jobs to run with Desktop closed, run the gateway as a service (hermes gateway install).

Creating and managing jobs

hermes cron (official docs)
bash
# In any chat (CLI, Desktop, Telegram, ...)
$/cron add "every 2h" "Check server status"
$/cron add "every 1h" "Summarize new feed items" --skill blogwatcher
$
# From a shell
$hermes cron create "every 2h" "Check server status" --name status-check
$hermes cron create "every 1h" "Post the digest" --paused # start paused, resume after review
$hermes cron list
$hermes cron edit status-check --schedule "every 4h" # names work in place of IDs
$hermes cron pause | resume | run | remove <job_id_or_name>
  • Asking in plain language works too: Hermes manages jobs through its cronjob_manage tool, so it can create, edit, pause, and remove them for you.
  • Each run starts a fresh agent session with no memory of your chat. Put everything the job needs in the prompt or in attached skills.
  • hermes cron run queues the job for the next scheduler tick; it still needs a running gateway or Desktop.
  • hermes pause stops every scheduled fire at once (manual runs still work); hermes resume lifts it and due work catches up.
  • Jobs are stored in ~/.hermes/cron/jobs.json and output in ~/.hermes/cron/output/<job_id>/. Each profile has its own. Edit through the CLI, chat, or dashboard rather than hand-editing the JSON.

Schedule formats

FormatExamplesRepeats
Relative delayin 30m, in 2h, in 1dOnce
Interval30m, every 2h, every hourUntil removed
Natural day/timeevery monday 9am, weekdays at 9am, daily at 7amUntil removed
Cron expression0 9 * * 1-5, 0 */6 * * *Until removed
ISO timestamp2026-10-01T09:00:00Once

Times use the machine's local timezone. A job firing at the wrong hour usually means the host clock or timezone differs from yours — compare date with hermes cron list.

Where the output goes

The agent's final answer is delivered automatically to the job's deliver target. The default is origin (the chat that created the job) on messaging platforms and local (files under ~/.hermes/cron/output/) from the CLI.

  • Platforms: telegram, telegram:<chat_id>, discord:#channel, slack, whatsapp, signal, email, and more; combine with commas, or use all for every connected home channel.
  • bot-chat drops the output into a Bot Mode bot's own chat as a message it then acts on — each delivery costs that bot a full agent turn.
  • Quiet monitors: if a successful run answers with [SILENT], nothing is sent (output is still saved). Failed runs always alert.
  • Delivery failure is its own status. A job whose run worked but whose message never arrived shows delivery_failed, not ok.
  • Outgoing messages are secret-redacted, but the saved output file keeps the response as written.

Which model a scheduled job uses

At fire time, current Hermes resolves the model in this order:

  1. A per-job pin — hermes cron create/edit --model … --provider …, or --pin to lock the current main model onto the job.
  2. cron.model — one default for every unpinned job, independent of your chat model (hermes config set cron.model <name>).
  3. Your main model at the moment the job fires. Change it with hermes model or /model and every unpinned job follows.

This rule changed twice in three months, so older guides and forum answers disagree with it. From June 2026 an unpinned job whose provider had changed since creation was skipped (#51051); v0.21.2 (September 11) made such jobs keep running on the model they were created with (#106499); v0.21.4 (September 21) replaced that with “follow the main model; pin on request” (#113679). If a job needs to stay on one model, pin it.

  • Pinned jobs never use your fallback_providers chain. Only unpinned jobs fall back to another provider when theirs fails; every job can still rotate between keys for the same provider.
  • The agent can lock the current model on request, but it cannot point a job at a different model — model choice stays with you.
  • A per-job reasoning effort (--reasoning-effort high) is set from the CLI only.
  • For unattended runs the docs suggest Nous Portal sign-in (hermes setup --portal) because its OAuth refresh is automatic.

Skills, folders, scripts, and context between runs

CapabilityHowWhat it does
Attach skills--skill a --skill bLoads each skill before the prompt, in order
Run in a project--workdir /abs/pathLoads that folder's AGENTS.md / CLAUDE.md and runs file and terminal tools there; otherwise jobs run detached from any repo
Script only, no model--no-agent --script check.shRuns a script from ~/.hermes/scripts/ and sends its stdout verbatim; empty output sends nothing. No tokens spent.
Skip the model when nothing changedA pre-run script printing {"wakeAgent": false}A pre-run script can decide the agent does not need to wake this time
Remember the last run--continuityInjects the job's own previous output, so a scout does not re-report the same items
Chain jobscontext_fromPrepends another job's latest output; set through the agent's cron tool (no CLI flag is documented)
Jobs that manage jobscron.allow_agent_scheduling: trueOff by default: scheduled runs cannot create or edit cron jobs

Bot Mode routines are cron jobs

In Hermes Desktop's Bot Mode, the Routines pane is a view over ordinary cron jobs named [bot:<name>] <routine>. They appear in hermes cron list and the dashboard's Cron page, belong to that bot's profile, and their results land in the bot's own chat. Turning Bot Mode off hides the pane but leaves the jobs in place.

Everything on this page therefore applies to routines, including the running requirement: a routine on a bot whose profile lives on your laptop fires only while that laptop is awake with the Desktop app or a gateway running.

Checking why a job did or didn't run

Diagnostics (official docs)
bash
$hermes cron status # is the scheduler alive? last tick, next run, OVERDUE warnings
$hermes cron list # per-job status, failure streak, delivery errors
$hermes cron doctor # read-only health check; exits 1 while anything is wrong
$hermes cron runs <job> --limit 20 # attempt history (alias: history)
$hermes cron incidents # repeated failures, alerted once; ack with: incidents ack <id>
$hermes gateway status
  • Overdue / OVERDUE means a due time passed more than 15 minutes ago without firing — the scheduler stopped. Restart the gateway or run the job by hand.
  • blocked_config: before any model call, Hermes checks the provider key, attached skills, delivery targets, and named MCP servers. A misconfigured job alerts once and spends no tokens.
  • Network not up yet (typical right after a laptop wakes): a recurring job that failed before reaching the model is retried after 5, 15, and 30 minutes.
  • Same error every run: alerted once, re-reminded after cron.failure_repeat_alert_hours (default 6); a nudge suggests pausing a job that failed 3 runs in a row.
  • A run mid-flight during a restart is recorded as unknown and not retried; the next scheduled tick fires normally. The docs state this is not an exactly-once guarantee for side effects.
  • A job can mark its own run failed by starting its answer with [CRON_FAILURE] on the first line.

Known problems (open as of September 26, 2026)

Under a systemd gateway, each job runs in a separate “restart-safe” worker process so a gateway restart does not kill it. That worker path has several open bug reports this week:

  • Workers failing with ModuleNotFoundError (for example ruamel) because they start without the gateway's dependencies — #122529, #123400, #124279.
  • Agent jobs failing with AuthError when keys come from a plugin-registered secret source — #121929.
  • Pinned jobs on a named custom provider stored as plain custom and then falling back silently — #119694.
  • Local Ollama models writing fake tool-call text in cron runs instead of calling tools — #123398. See local models.

Separately documented: on hosts without a user systemd session (containers, minimal LXCs, a service user without lingering), workers run without that isolation and a gateway restart kills an in-progress job. The documented fix is sudo loginctl enable-linger <user>.

Community report: These are user bug reports on GitHub, not confirmed defects; some may be closed by the time you read this. Check each issue's status and the latest release notes.

When an always-on machine becomes necessary

If a job must run while your personal computer sleeps or is offline, the scheduler has to live on a machine that stays on: a home server or mini PC, a VPS with the gateway installed as a service, or a managed option such as Hermes Cloud. The trade-offs between those are on Hermes hosting. If a daily job that simply catches up when you open your laptop is good enough, you don't need any of that.

Every agent run is a model request, so frequent schedules add to your model bill; script-only jobs do not. To see what each job actually costs in tokens and dollars, see Hermes Cron Cost.

Not tested by this site: This page organizes the official cron, cron troubleshooting, and Bot Mode docs plus release notes and GitHub issues. We have not run a long-lived cron fleet ourselves, so we make no claims about how reliably jobs fire on any particular host.

Primary sources

HermesAgentAI.org is an independent educational documentation resource and community guide. It is not affiliated with, sponsored by, or endorsed by Nous Research or FlyHermes. Hermes Agent is released under the MIT License by Nous Research.

Where to go next