[READ-ONLY] Mirror of https://github.com/mrgnw/koku. A cron daemon written in Rust — 刻
koku#
A system-level cron daemon written in Rust. Japanese for "to mark/carve time" (刻).
Single binary that manages and runs scheduled jobs, with an integration point for kagaya to surface cron status and trigger one-off runs. CLI alias: ku.
What it is#
- A single binary (
koku) —ku daemon startruns the daemon, all other subcommands talk to it via Unix socket - CLI for managing jobs: status, one-off runs, pause/resume, log viewing
- A library crate others can embed if needed
Architecture#
- Scheduler:
cronerfor cron expression parsing, custom scheduler loop on top of tokio - Daemon:
ku daemon startruns the scheduler in background (ku daemon runfor foreground). Unix socket IPC (via muzan) for CLI ↔ daemon communication - Config: TOML file defining jobs — name, cron expression, command, working dir, error policy
- Logging: Per-job structured log output (job name, exit code in every line)
- Process execution: Spawn jobs as child processes, capture stdout/stderr, track exit codes
Config format#
[[job]]
name = "backup"
cron = "0 2 * * *"
command = "bash backup.sh"
dir = "/home/user/scripts"
on_error = "backoff" # continue | backoff | stop (default: continue)
overlap = false # allow concurrent runs (default: false)
timeout = "30m" # kill job after duration (optional)
[[job]]
name = "cleanup"
cron = "*/15 * * * *"
command = "python3 cleanup.py"
on_error policy (from Jobber's model)#
continue— ignore failures, keep scheduling (default)backoff— exponential backoff on failure, resume normal schedule on successstop— disable the job after repeated failures. Requires manualku resumeto re-enable
Job states#
idle waiting for next scheduled run
running currently executing
paused manually paused via `koku pause`
failing last run errored, will retry with backoff (on_error = backoff)
stopped disabled after repeated failures (on_error = stop). manual resume required
CLI#
ku init # scaffold ~/.config/koku/config.toml with examples
ku check # validate config, preview next-run times
ku daemon start # start daemon in background
ku daemon stop # stop daemon gracefully
ku daemon status # show daemon pid/uptime
ku status # table of all jobs with state/timing
ku status --json # machine-readable
ku run <name> # trigger one-off run
ku pause <name> # pause a job without editing config
ku resume <name> # resume a paused/stopped job
ku reload # reload config without restarting
Status output#
NAME STATE LAST RUN EXIT NEXT RUN
backup idle 2026-02-18 02:00:00 0 2026-02-19 02:00:00
cleanup running 2026-02-18 14:15:00 — —
sync failing 2026-02-18 14:00:00 1 2026-02-18 14:30:00
deploy paused 2026-02-17 18:00:00 0 —
Kagaya integration#
kagaya connects to koku's Unix socket to:
- Display cron job status in the process supervisor UI
- Trigger one-off runs from within kagaya
Crates#
muzan— daemon lifecycle (Unix socket IPC, PID management, auto-start). Path dep:~/dev/muzantokio— async runtimecroner— cron expression parsing (lightweight, no scheduler opinions)serde+toml— config parsingclap— CLItracing— structured logging (with job name, exit code fields)comfy-table— status table output
Design influences#
- Jobber (Go, unmaintained) — error handling model (continue/backoff/stop), error vs failure distinction,
test/pause/resumecommands,initscaffolding - Supercronic (Go) — structured log fields per job (iteration, schedule, command), overlap detection with warnings,
-testflag for config validation - Cronitor CLI (Go) —
--jsonflag on every command,pause --hourstimed pause, progressive disclosure in output - Healthchecks.io (Python) — clean state machine (idle/running/late/down), grace period concept
- Cronie (C) —
cronnextfor previewing schedules (→koku check)
No Rust CLI cron manager exists. koku fills that gap.
Future (post-v1)#
ku log <name>— per-job log viewing (requires per-job log files)- Notification hooks (
on_failurecommand per job, webhook support) - Timed pause (
ku pause <name> --hours 24) - Random schedule jitter (Jobber's
R, Cronie's~) - Env vars per job in config
Web dashboard is provided by kagaya (ky serve), which connects to koku's Unix socket for cron status, one-off runs, and pause/resume.
Naming#
- Crate:
koku - Binaries:
koku+ku(alias) - Daemon:
ku daemon start/ku daemon run - Named after 刻 (koku) — Japanese for "to carve/mark time"