Scheduled Tasks
Demi can create, manage, and monitor scheduled tasks using NixOS systemd timers. These are declarative, survive reboots, and can be rolled back like any other NixOS change.
Creating a Timer
You: back up my postgres database every night at 2am
Demi: Here's the plan:
- Timer: nurvus-backup-postgres
- Schedule: *-*-* 02:00:00 (daily at 2am)
- Command: podman exec postgres pg_dump -U postgres mydb > /srv/backups/postgres/$(date +%Y%m%d).sql
- Creates /srv/backups/postgres/ directory
Ready to proceed?
You: yes
Demi: Timer added. Rebuilding to activate.
★ nixos_rebuild (action=switch)
Backup scheduled. First run at 2am tonight.
Schedule Formats
Demi uses systemd calendar notation:
| Schedule | Meaning |
|---|---|
*-*-* 02:00:00 |
Daily at 2am |
hourly |
Every hour |
daily |
Every day at midnight |
weekly |
Every Monday at midnight |
*-*-* *:00/15:00 |
Every 15 minutes |
Mon *-*-* 09:00:00 |
Every Monday at 9am |
*-*-01 00:00:00 |
First of every month |
Managing Timers
You: what timers are running?
Demi: ★ timer (action=list)
Scheduled tasks (2):
backup-postgres [enabled]
Schedule: *-*-* 02:00:00
update-blocklists [enabled]
Schedule: weekly
You: disable the postgres backup
Demi: Disabling timer nurvus-backup-postgres. Ready to proceed?
You: yes
Demi: Timer disabled. Rebuild complete.
You: remove the blocklist updater
Demi: Removing timer nurvus-update-blocklists. This will delete the scheduled task.
Ready to proceed?
You: yes
Demi: Timer removed. Rebuild complete.
Running Tasks Immediately
You can run any scheduled task right now without waiting for its schedule:
You: run the postgres backup now
Demi: ★ timer (action=run, name=backup-postgres)
Started nurvus-backup-postgres.service.
One-Off Scheduled Tasks
Need to run something once at a specific time? Use run_at for a transient timer that doesn't require a rebuild:
You: restart the minecraft server at midnight tonight
Demi: ★ timer (action=run_at, name=restart-minecraft,
schedule=*-*-* 00:00:00, command=systemctl restart podman-minecraft)
Scheduled one-off task for midnight. This won't survive a reboot.
You: back up postgres in an hour
Demi: ★ timer (action=run_at, name=backup-postgres-now,
schedule=+1h, command=podman exec postgres pg_dump ...)
Scheduled. Will run in 1 hour.
One-off tasks are transient and won't survive a reboot. Use add for recurring tasks that need to persist.
Common Use Cases
Database backups: - "back up postgres every night" - "dump the nextcloud database weekly"
Container maintenance: - "restart the minecraft server every Sunday at 4am" - "update pi-hole's gravity list daily"
Monitoring: - "check if nginx is responding every 5 minutes and restart it if not"
Cleanup: - "delete postgres backups older than 30 days every week" - "clean up old container images monthly"
How It Works
Under the hood, Demi adds two blocks to configuration.nix:
- A systemd service (oneshot) that runs the command
- A systemd timer that triggers the service on schedule
All managed timers are prefixed with nurvus- so they don't conflict with system timers. Disabling a timer sets its wantedBy to an empty list so it stays in the config but doesn't activate.