Skip to main content

Replace cron with a web UI, logs and retries

To replace cron, move each crontab line into Windmill as a script plus a schedule with the same cron expression. You keep your Bash, Python or PowerShell code, and get a web UI to see and edit schedules, a log and result for every run, a Run button for manual runs, and retries. Jobs run on Windmill workers instead of one machine's crontab, so the schedule keeps working when that machine is replaced.

1. Move the job into a script​

Take this crontab line:

0 2 * * * /opt/scripts/rotate_logs.sh /var/log/myapp 14

The script becomes a Windmill Bash script. Positional arguments of the form name="${1:-default}" become named parameters, with a form in the UI:

# Was in crontab: 0 2 * * * /opt/scripts/rotate_logs.sh /var/log/myapp 14
log_dir="${1:-/tmp/myapp-logs}"
keep_days="${2:-14}"

mkdir -p "$log_dir"
echo "Deleting .log files older than $keep_days days in $log_dir"
find "$log_dir" -name '*.log' -mtime +"$keep_days" -print -delete
echo "Done"

Windmill reads log_dir and keep_days as two string parameters with defaults /tmp/myapp-logs and 14. Save it as f/ops/rotate_logs in the script editor, or push it with the CLI:

wmill generate-metadata f/ops --yes
wmill script push f/ops/rotate_logs.sh

The script runs on the worker, so it sees the worker's filesystem, not the old server's. For files on a specific machine, run a worker on that machine and route the job to it with a worker tag, or have the script reach the machine over SSH or an API.

2. Add the schedule​

A crontab expression has five fields. Windmill cron expressions have six, starting with seconds, and a five-field expression is rejected, so 0 2 * * * becomes:

0 0 2 * * *

Add the schedule from the script's Triggers tab or the Schedules page, set the timezone (cron on a server uses the server's local time; a Windmill schedule uses the timezone you pick), and set the arguments, here log_dir: /var/log/myapp and keep_days: 14. See cron syntax for extensions such as L (last day of the month) and # (nth weekday).

One script can have several schedules with different arguments, for example one per log directory.

3. What you get compared with crontab​

With crontabWith a Windmill schedule
Output goes to mail or a log file you set upEvery run keeps its logs, arguments, result and duration, in the runs page
Manual runs from a shell on the serverRun the script from its form, with the same arguments or different ones
Editing means SSH and crontab -eSchedules are listed and edited in the web UI, with roles and folders controlling who can change them
A failed run is silent unless the script reports itA failure is marked in the run history; retries and alerts are configurable (see below)
Secrets in environment files on the serverVariables and secrets, encrypted in the database
Tied to one machineRuns on any worker of the matching worker group

4. Retries and failure alerts​

There are two ways to retry a failed scheduled job:

  • Schedule-level retries for a script, set in the schedule's Retries tab. This is an Enterprise Edition feature on self-hosted instances.
  • Step retries in a flow, available on every edition. Wrap the script in a one-step flow and schedule the flow:
summary: Rotate logs, with retries
value:
modules:
- id: a
value:
type: script
path: f/ops/rotate_logs
input_transforms: {}
retry:
constant:
attempts: 2
seconds: 60

With attempts: 2, a failing step runs up to three times in total: the first try and two retries, 60 seconds apart. With input_transforms: {} the script runs with its default arguments; map the flow's inputs to the script's parameters to pass other values. Exponential backoff is also available.

To be told when a scheduled job fails, attach a schedule error handler (for example the pre-set Slack or Teams handler) and a recovery handler for when it succeeds again. Both are Cloud and Enterprise Edition features. On the Community Edition, add a flow error handler to the scheduled flow, which runs when a step fails.

Edition notes​

On a self-hosted Community Edition, schedules, run logs, manual runs and flow step retries are included, and the runs history is kept for up to 30 days. Schedule-level retries, schedule error and recovery handlers, and longer run retention need a Cloud plan or the Enterprise Edition. See pricing for the full list.