# `jan cron`
Daemon-backed scheduler for `cron:` script leaves. The daemon ticks every **100 ms**.
`jan cron start` / `stop` manage the daemon; `--list` reads its in-memory schedule cache
(not the YAML tree on disk).
```bash
jan cron start # start daemon (systemd when available)
jan cron stop # stop daemon
jan cron status
jan cron refresh # reload cache after editing YAML cron:
jan cron --list # cached schedules (daemon must be running)
jan cron --list --at "2026-08-05 09:00"
jan cron --dry-run --at "2026-08-05 10:30:00" # one-shot; no daemon
jan cron --help
```
## Lifecycle
| `start` | Start the daemon; installs `~/.config/systemd/user/jan-cron.service` when `systemctl --user` is available, otherwise starts a background process |
| `stop` | Stop the daemon and disable/remove the systemd user service |
| `status` | Report pid, uptime, schedule count, cache age, and preferred tree |
| `refresh` | Reload the in-memory schedule cache from the preferred YAML tree (`reload` is an alias) |
## Schedule cache
On start (and on `refresh`), the daemon walks the preferred tree once and stores every
script with a `cron:` field. The tick loop and `jan cron --list` use that cache only.
After editing `cron:` in YAML, run `jan cron refresh`.
Control socket: `$XDG_RUNTIME_DIR/jan-cli/cron.sock` (fallback: `$JAN_CONFIG_DIR/run/cron.sock`).
## One-shot testing (no daemon)
`--dry-run` and `--at` (without `--list`) evaluate schedules in-process:
```bash
jan cron --dry-run --at "2026-08-05 10:30" # minute match
jan cron --dry-run --at "2026-08-05 10:30:45" # second match
jan cron --at "2026-08-05 10:30" # run matches once
```
## Schedule granularity
See [spec/cron.md](../spec/cron.md) for five-, six-, and seven-field expressions.
Prefer `jan use` so the daemon can resolve your tree.