# Time triggers
Put a crontab expression (or a list of them) on a script node or its `run` child.
The **jan cron daemon** ticks every 100 ms, evaluates schedules, and runs matching
`run` leaves. Start it with `jan cron start`; stop with `jan cron stop`.
```yaml
commands:
scripts:
commands:
misc:
commands:
morning-note:
about: Append a daily note
cron: "30 10 * * *" # minute (5 fields)
# cron: "* * * * * *" # every second (6 fields)
# cron: "*/5 * * * * * *" # every 500 ms (7 fields)
commands:
run:
exec:
argv: ["bash", "-lc", "echo hi >> ~/cron.txt"]
```
CLI details: [`jan cron`](../cli/cron.md).
## Expression syntax
Field counts determine granularity:
| 5 | minute | `30 10 * * *` |
| 6 | second | `0 * * * * *` (top of each minute) |
| 7 | 100 ms | `*/5 * * * * * *` (every 500 ms) |
Seven-field order: `decisecond second minute hour day-of-month month day-of-week`
(decisecond is 0–9, one tick = 100 ms).
Six-field order: `second minute hour day-of-month month day-of-week`.
Five-field order: `minute hour day-of-month month day-of-week` (unchanged).
Supported tokens per field: `*`, `N`, `A,B`, `A-B`, `*/S`, `A-B/S`.
| decisecond | 0–9 |
| second | 0–59 |
| minute | 0–59 |
| hour | 0–23 |
| day of month | 1–31 |
| month | 1–12 |
| day of week | 0–7 (0 and 7 are Sunday) |
Month/weekday **names** are not supported — use numbers.
Matching uses **local civil time**. Day-of-month and day-of-week are ANDed (both must match).
## Nicknames
| `@yearly` / `@annually` | `0 0 1 1 *` |
| `@monthly` | `0 0 1 * *` |
| `@weekly` | `0 0 * * 0` |
| `@daily` / `@midnight` | `0 0 * * *` |
| `@hourly` | `0 * * * *` |
| `@every_second` | `* * * * * *` |
| `@every_100ms` | `* * * * * * *` |
Install the daemon:
```bash
jan cron start
jan cron status
jan cron refresh # after editing cron: in YAML
jan cron stop
```