CLI Reference
Horsies provides a clap-based CLI (horsies) for running workers, the scheduler, and validation checks. In Rust, tasks are registered at compile time, so the CLI takes a configuration source (config file path or database URL) instead of a Python module path.
Commands
Section titled “Commands”horsies worker
Section titled “horsies worker”Start a task worker.
horsies worker [CONFIG] [OPTIONS]Arguments:
| Argument | Description |
|---|---|
CONFIG | Path to a config file (TOML/JSON) or database URL (positional, optional) |
Options:
| Option | Default | Description |
|---|---|---|
-m, --module CONFIG | — | Config source (alternative to positional argument; takes precedence) |
-q, --queues QUEUES | default | Comma-separated queue names |
-c, --concurrency N | CPU count | Maximum concurrent tasks |
--max-claim-batch N | 2 | Max claims per queue per pass |
--max-claim-per-worker N | 0 | Max total claimed tasks (0=auto) |
--coalesce-notifies N | 100 | NOTIFY messages to drain per wake |
--loglevel LEVEL | info | debug, info, warning, error |
Examples:
# Start worker with a config filehorsies worker ./config/horsies.toml
# Start worker with a database URLhorsies worker -m "postgresql://user:pass@localhost/mydb"
# Custom concurrency and queueshorsies worker ./config/horsies.toml -q high,low --concurrency 8
# Debug logginghorsies worker ./config/horsies.toml --loglevel debug
# Production settingshorsies worker ./config/horsies.toml --concurrency 8 --max-claim-batch 4 --loglevel warningProgrammatic Alternative
Section titled “Programmatic Alternative”In most Rust projects, you start the worker directly in your binary:
use horsies::{Horsies, AppConfig, WorkerConfig};
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let mut app = Horsies::new(AppConfig::for_database_url("postgresql://..."))?;
// Register tasks my_task::register(&mut app)?;
// Start worker with defaults app.run_worker().await?;
// Or with custom config let worker_config = WorkerConfig { concurrency: 8, queues: vec!["high".into(), "low".into()], ..Default::default() }; app.run_worker_with(worker_config).await?;
Ok(())}horsies scheduler
Section titled “horsies scheduler”Start the scheduler service.
horsies scheduler [CONFIG] [OPTIONS]Arguments:
| Argument | Description |
|---|---|
CONFIG | Path to a config file or database URL |
Options:
| Option | Default | Description |
|---|---|---|
-m, --module CONFIG | — | Config source (alternative to positional argument) |
--loglevel LEVEL | info | debug, info, warning, error |
--check-interval N | from config | Override check interval in seconds (1-60) |
--dry-run | false | Validate schedules without starting the loop |
Examples:
# Start schedulerhorsies scheduler ./config/horsies.toml
# Debug logginghorsies scheduler ./config/horsies.toml --loglevel debug
# Validate schedules without runninghorsies scheduler ./config/horsies.toml --dry-runProgrammatic alternative:
app.run_scheduler().await?;horsies check
Section titled “horsies check”Validate configuration, task registration, and optionally broker connectivity without starting services.
For details on validation phases, see Startup Validation.
horsies check [CONFIG] [OPTIONS]Arguments:
| Argument | Description |
|---|---|
CONFIG | Path to a config file or database URL |
Options:
| Option | Default | Description |
|---|---|---|
-m, --module CONFIG | — | Config source (alternative to positional argument) |
--loglevel LEVEL | warning | debug, info, warning, error |
--live | false | Also connect to PostgreSQL, ensure the Horsies schema, and run SELECT 1 |
Examples:
# Validate config and task registrationhorsies check ./config/horsies.toml
# Include broker connectivity checkhorsies check ./config/horsies.toml --liveProgrammatic alternative:
app.check()?;// or with live DB check:app.check_live().await?;horsies get-docs
Section titled “horsies get-docs”Fetch the full documentation locally as markdown files. Useful for AI agents (Claude Code, Cursor, Copilot, etc.) that need to read docs without web requests.
horsies get-docs [OPTIONS]Options:
| Option | Default | Description |
|---|---|---|
--output DIR | .horsies-docs | Output directory |
Examples:
# Fetch docs to default locationhorsies get-docs
# Custom output directoryhorsies get-docs --output my-docs/
# Update existing docs (idempotent -- overwrites cleanly)horsies get-docsUses git sparse checkout when git is available, falls back to tarball download otherwise. No app instance or database connection required.
Agent Skills (Repository)
Section titled “Agent Skills (Repository)”If you are using an AI coding agent from a source checkout, Horsies also ships guidance-oriented skill files in:
horsies/.agents/skills/
Available files:
SKILL.md— quick orientation and routingtasks.md— task authoring, send/retry, serialization, error handlingworkflows.md— DAG construction, handles, failure semantics, validationconfigs.md— configuration, scheduling, CLI checks, environment variables
These files are documentation-focused (no bundled scripts) and are intended for on-demand loading by agents that support markdown skill files.
Process Signals
Section titled “Process Signals”Both commands handle graceful shutdown:
| Signal | Behavior |
|---|---|
SIGTERM | Graceful shutdown |
SIGINT (Ctrl+C) | Graceful shutdown |
Workers wait for running tasks to complete before exiting.
Exit Codes
Section titled “Exit Codes”| Code | Meaning |
|---|---|
| 0 | Clean shutdown |
| 1 | Error (check logs) |
Environment Variables
Section titled “Environment Variables”export DATABASE_URL=postgresql://...horsies worker "$DATABASE_URL"The CLI does not inject DATABASE_URL into config files or load .env automatically. Use a config file path as the positional argument, or pass the database URL directly as the config source.
Logging can be controlled with RUST_LOG:
# Fine-grained log controlRUST_LOG=horsies=debug,sqlx=warn horsies worker ./config/horsies.tomlWhen RUST_LOG is set, it takes precedence over the --loglevel flag.
Deployment
Section titled “Deployment”Systemd
Section titled “Systemd”[Unit]Description=Horsies WorkerAfter=postgresql.service
[Service]Type=simpleUser=appWorkingDirectory=/appExecStart=/usr/local/bin/myapp-workerRestart=alwaysEnvironment=DATABASE_URL=postgresql://user:pass@localhost/db
[Install]WantedBy=multi-user.targetDocker
Section titled “Docker”FROM rust:1.75 AS builderWORKDIR /appCOPY . .RUN cargo build --release
FROM debian:bookworm-slimRUN apt-get update && apt-get install -y libssl3 ca-certificates && rm -rf /var/lib/apt/lists/*COPY --from=builder /app/target/release/myapp-worker /usr/local/bin/CMD ["myapp-worker"]Procfile
Section titled “Procfile”worker: ./target/release/myapp-workerscheduler: ./target/release/myapp-scheduler