AI agents are powerful, but they shine brightest when they work without you. Hermes Agent's built-in cron scheduler lets you define recurring tasks — content publishing, system monitoring, data pipelines — that run autonomously on a schedule. No external cron daemons, no fragile shell scripts, no manual intervention. This guide covers everything from creating your first job to running a fleet of 11 production cron jobs that manage a multi-site publishing network, every command verified on live hardware.
System cron (crontab) can run any command, but piping an LLM agent through it is fragile. You need to manage Python virtualenvs, API keys in environment files, output logging, and error handling. Hermes's built-in scheduler solves all of this:
Let's verify the scheduler is running:
$ hermes cron status
✓ Gateway is running — cron jobs will fire automatically
PID: 287
Ticker heartbeat: 2s ago
11 active job(s)
Next run: 2026-08-08T04:00:00+00:00
The gateway process runs the ticker. If you see "Gateway is running", your jobs are live. If not, start Hermes normally and it'll spin up the scheduler automatically.
The simplest cron job: run an agent every hour with a fixed prompt.
$ hermes cron create "0 * * * *" "Check if all Docker containers are healthy and report any issues"
✓ Job created and activated
ID: a1b2c3d4e5f6
Name: (auto-generated)
Repeat: ∞
Next: 2026-08-08T05:00:00+00:00
When the clock hits the top of the hour, Hermes spins up a new conversation, injects your prompt, and lets the agent run with full access to its tools — terminal, file system, web search, and any skills you've attached. The agent can run docker ps, grep logs, and report back.
Production cron jobs need names and skills. Here's a real content-publishing job:
$ hermes cron create \
--name "agentrule-daily" \
--skill "content-site-publisher" \
--deliver local \
"0 5 * * *" \
"Generate one new verified AI agent tutorial for agent-rule.com."
✓ Job created and activated
ID: 8347a5612ed1
Name: agentrule-daily
Repeat: ∞
Next: 2026-08-09T05:00:00+08:00
This job fires every day at 5 AM, loads the content-site-publisher skill (which contains the full publishing workflow: SSH to server, create HTML, update index, update sitemap), and delivers the result locally — meaning the agent's final response is the deliverable.
Hermes accepts standard cron syntax plus human-readable shortcuts:
# Standard cron: minute hour day month weekday
"0 4 * * *" # Daily at 4 AM UTC
"30 6 * * *" # Daily at 6:30 AM UTC
"0 */6 * * *" # Every 6 hours
# Human-readable shortcuts
"30m" # Every 30 minutes
"every 2h" # Every 2 hours
"every day at 9am" # Daily at 9 AM
Once you have multiple jobs, you need visibility and control:
$ hermes cron list
┌─────────────────────────────────────────────────────────────────────────┐
│ Scheduled Jobs │
└─────────────────────────────────────────────────────────────────────────┘
8347a5612ed1 [active]
Name: agentrule-daily
Schedule: 0 5 * * *
Repeat: ∞
Next run: 2026-08-09T05:00:00+08:00
Deliver: local
Skills: content-site-publisher
Last run: 2026-08-07T13:06:09+08:00 ok
afe8447f1609 [active]
Name: newspecies-zh-daily
Schedule: 0 8 * * *
Repeat: ∞
Next run: 2026-08-08T08:00:00+08:00
Deliver: local
Skills: content-site-publisher
Last run: 2026-08-07T16:08:13+08:00 ok
fef135d5d76e [active]
Name: arablaw-daily
Schedule: 0 4 * * *
Repeat: ∞
Next run: 2026-08-08T04:00:00+00:00
Deliver: local
Skills: content-site-publisher
Last run: 2026-08-07T04:07:50+00:00 ok
The output shows each job's ID, name, schedule, delivery target, attached skills, and last run status. The ok means the agent completed successfully. Failed runs show the error.
Need to temporarily stop a job without deleting it?
$ hermes cron pause 8347a5612ed1
✓ Job paused
$ hermes cron resume 8347a5612ed1
✓ Job resumed — next run at 2026-08-09T05:00:00+08:00
Change the schedule, add skills, or modify the prompt:
$ hermes cron edit 8347a5612ed1 --skill "another-skill"
hermes cron edit keeps the same identity.Test a job immediately without waiting for its schedule:
$ hermes cron run 8347a5612ed1
✓ Queued for next tick
Or run all due jobs right now:
$ hermes cron tick
✓ Ran 2 due jobs
agentrule-daily: ok
tools-daily: ok
Cron jobs can deliver results to different channels. This is how a single agent fleet serves multiple audiences:
# Local — result appears in your Hermes session (or is stored for review)
--deliver local
# Telegram — result sent as a message to a chat
--deliver telegram:123456789
# Discord — result posted to a Discord channel
--deliver discord:webhook_url
For silent background jobs (monitoring, data pipelines), use --deliver local. The result is stored but doesn't interrupt you. For alerts, use Telegram or Discord to get notified when something needs attention.
Without skills, every cron run is an open-ended conversation — the agent might solve the problem differently each time, and sometimes not at all. Skills lock in your proven approach.
Here's the difference:
# WITHOUT skill — the agent improvises
$ hermes cron create "0 6 * * *" "Translate new English articles to Chinese"
# WITH skill — the agent follows a battle-tested workflow
$ hermes cron create \
--skill "content-site-publisher" \
"0 6 * * *" \
"Translate yesterday's new English article to Chinese"
The content-site-publisher skill contains: the SSH jump host chain, exact directory paths, hreflang patterns, template HTML structure, index page insertion format, and sitemap update procedure. The agent doesn't guess — it follows the playbook.
skills/ directory. They're version-controlled with Git, editable with any text editor, and shared across your team's Hermes profiles. When you discover a better approach in a cron run, update the skill — every future run benefits.For production deployments, run Hermes in a Docker container with the gateway process (which hosts the cron scheduler) always running:
$ docker --version
Docker version 20.10.24+dfsg1, build 297e128
A typical Docker setup for Hermes with cron jobs:
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y \
python3 python3-pip python3-venv \
curl git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Install Hermes
RUN python3 -m venv /opt/hermes-venv
ENV PATH="/opt/hermes-venv/bin:$PATH"
RUN pip install hermes-agent
# Mount your profile and workspace
VOLUME /root/.hermes
VOLUME /workspace
WORKDIR /workspace
# Running Hermes interactively starts the gateway + cron scheduler
CMD ["hermes"]
With Docker Compose, pair Hermes with its dependencies:
# docker-compose.yml excerpt
services:
hermes:
build: .
volumes:
- ~/.hermes:/root/.hermes # profiles, skills, config
- ./workspace:/workspace # project files
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: hermes
POSTGRES_USER: hermes
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
The restart: unless-stopped ensures Docker brings Hermes back after reboots — and with it, the cron scheduler resumes firing on schedule.
Version-control your cron jobs by managing your Hermes profile with Git:
$ git --version
git version 2.39.5
# Your Hermes profile IS your cron configuration
$ ls ~/.hermes/profiles/yiman/
config.yaml skills/ plugins/ cron/ memories/
# Cron job definitions live in the profile's cron/ directory
$ ls ~/.hermes/profiles/yiman/cron/
8347a5612ed1.yaml afe8447f1609.yaml fef135d5d76e.yaml ...
Each .yaml file is a serialized cron job. You can:
config.yaml should reference environment variables (e.g., ${OPENAI_API_KEY}), not hardcoded secrets. Use Docker's .env file or your host's environment for credentials.Hermes stores conversation history in a local SQLite database. For production monitoring across multiple agents, im-bot uses PostgreSQL with Prisma ORM:
$ psql --version
psql (PostgreSQL) 15.18 (Debian 15.18-0+deb12u1)
A cron execution tracking table:
CREATE TABLE cron_executions (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
job_id VARCHAR(64) NOT NULL,
job_name VARCHAR(128),
started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
finished_at TIMESTAMPTZ,
status VARCHAR(16) DEFAULT 'running',
-- CHECK (status IN ('running', 'ok', 'failed')),
error_message TEXT,
output_summary TEXT,
skill_used VARCHAR(64)
);
CREATE INDEX idx_cron_executions_job_id ON cron_executions(job_id);
CREATE INDEX idx_cron_executions_started ON cron_executions(started_at DESC);
Query your cron fleet's health:
SELECT job_name, status, started_at, finished_at
FROM cron_executions
WHERE started_at > now() - INTERVAL '24 hours'
ORDER BY started_at DESC;
This gives you a dashboard of what ran when, what succeeded, and what failed — without digging through individual conversation logs.
Not every scheduled task needs an AI agent. Hermes supports script-only cron jobs that run a script on schedule and deliver its output — no LLM call at all:
$ hermes cron create \
--name "disk-alert" \
--script "check-disk.sh" \
--no-agent \
--deliver telegram:123456789 \
"*/30 * * * *"
Scripts live in ~/.hermes/scripts/. The --no-agent flag skips the LLM entirely — the script's stdout is delivered directly. This is perfect for classic watchdog tasks: disk space alerts, memory usage monitors, CI pipeline status pings.
Here's the architecture that runs this very tutorial. At 5 AM daily, the agentrule-daily job fires:
content-site-publisher skill loadedThe entire publishing pipeline — from blank page to deployed HTML — runs without human intervention. The same pattern powers the multi-language publishing for thenewspecies.xyz (11 cron jobs, staggered across 4 AM to 10 AM UTC to avoid rate-limit collisions).
When running multiple LLM-powered cron jobs, stagger them to avoid API rate limits:
04:00 UTC — arablaw-daily (English)
05:00 UTC — agentrule-daily (English)
06:00 UTC — newspecies-daily (English)
06:30 UTC — agentrule-zh-daily (Chinese translation)
07:00 UTC — arablaw-ar-daily (Arabic translation)
07:30 UTC — arablaw-zh-daily (Chinese translation)
08:00 UTC — newspecies-zh-daily (Chinese translation)
08:30 UTC — newspecies-ar-daily (Arabic translation)
09:00 UTC — aitools-daily (English)
09:30 UTC — tools-daily (English)
10:00 UTC — zhai-daily (English)
Each job gets its own 30-minute window, ensuring the LLM provider isn't hit with simultaneous requests. This is critical for API providers with concurrent-request limits.
restart: unless-stopped — the gateway process (and its cron scheduler) survives rebootscron_executions table gives you a dashboard of your fleet's health--no-agent for disk alerts, memory monitors, CI pingsHermes cron jobs turn your AI agent from a tool you use into a system that runs itself. The 11-job fleet described above publishes content across 6 websites in 3 languages — every day, without a single manual step. That's the power of scheduled agent automation.