Cron Job with timeout
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Cron jobs can hang indefinitely if a script stalls on network I/O, a locked resource, or a bug. The timeout command (GNU coreutils) wraps any command with a time limit, killing it if it exceeds the specified duration. Combining timeout with cron ensures that stuck jobs do not pile up, consume resources, or block the next scheduled run.
Basic Cron with Timeout
Duration suffixes: s (seconds, default), m (minutes), h (hours), d (days).
How timeout Works
Sending SIGKILL After SIGTERM
Some processes ignore SIGTERM. Use --kill-after to send SIGKILL as a follow-up:
The sequence is: wait 5 minutes, send SIGTERM, wait 10 more seconds, send SIGKILL.
Specifying the Signal
Preventing Overlapping Cron Jobs
Use flock to ensure only one instance runs at a time:
Timeout in Scripts
Alternative: Using timelimit
On systems without GNU timeout:
Cron Job with Timeout and Email Notification
More robust version with a wrapper script:
Systemd Timer Alternative
For more control than cron, use systemd timers with built-in timeout:
Common Pitfalls
- Not accounting for cron's PATH: Cron runs with a minimal PATH.
timeoutmay not be found if it is in/usr/local/bin. Use the full path (/usr/bin/timeout) or set PATH at the top of the crontab. - Timeout shorter than expected run time: If a job normally takes 4 minutes and you set a 3-minute timeout, it will be killed on every run. Set the timeout to at least 2x the normal duration to account for variability.
- Processes ignoring SIGTERM: Some programs (Java apps, background process groups) ignore SIGTERM. Always add
--kill-after=10sto send SIGKILL as a backup. Without it, the process may run indefinitely despite the timeout. - Not logging timeout events: Without checking
$?for exit code 124, you will not know the job was killed. Always log or alert on timeouts so you can investigate the root cause. - Child processes surviving the timeout:
timeoutkills the direct child process, but grandchild processes may survive. Usetimeout --foregroundorsetsidto ensure the entire process group is killed.
Summary
- Use
timeout 5m /path/to/script.shin crontab to prevent hung jobs - Add
--kill-after=10sto send SIGKILL if the process ignores SIGTERM - Use
flock -nalongsidetimeoutto prevent overlapping cron executions - Check exit code 124 to detect and log timeout events
- Use full paths for
timeoutin cron (e.g.,/usr/bin/timeout) - Consider systemd timers with
TimeoutStartSecfor more robust scheduling

