The cron expression for “every minute” is the maximally-permissive form:
* * * * *
Every field is a wildcard. The job fires at every minute of every hour of every day. 60 fires per hour, 1440 per day. The page above generates this schedule; this companion is the warning label.
When every-minute is the right answer
- Fast retry of failed work. A queue worker that polls for retries every minute keeps recovery latency under a minute.
- Watchdog scripts. Detect crashed services within a minute of failure.
- Near-real-time polling of systems that don’t push events — pulling new rows from an external database, watching for new files in a directory.
- High-frequency cleanup of short-lived state that accumulates fast.
When you need lower latency than this — sub-second SLAs — cron is the wrong tool. Use a daemon, a queue, or an event subscription.
When every-minute is wrong
- The job takes more than a minute. Overruns and overlaps. A
* * * * *job that sometimes takes 70 seconds is now running multiple instances simultaneously. This is the most common bug with this cadence. - The job is heavy. 1440 runs/day of anything non-trivial is a lot of compute. Audit cost before adopting.
- You’re using cron as a substitute for a daemon. A daemon that sleeps and wakes up every minute is more efficient, more responsive, and easier to instrument than fork-a-fresh-process every minute.
- Real-time matters. Cron is best-effort. Under load, “every minute” can drift to “every 75 seconds.” For monitoring SLAs that depend on exact timing, use a real-time scheduler.
Overlap protection is mandatory
Any * * * * * job that might take more than a minute needs to refuse to start when a previous instance is still running. Standard idioms:
Linux: flock
* * * * * flock -n /tmp/myjob.lock /path/to/script.sh
-n makes flock fail immediately rather than wait, so the second invocation no-ops.
In-script lock file
[ -e /tmp/myjob.pid ] && exit 0
echo $$ > /tmp/myjob.pid
trap 'rm -f /tmp/myjob.pid' EXIT
# ...job body...
Application-level state
A database row or Redis key the job sets at start and clears on completion. Use a TTL so a crashed job doesn’t permanently lock the schedule.
Without one of these, every-minute jobs are an outage waiting to happen.
Output handling
cron mails the output of every job to the user it runs as. A job firing 1440 times a day with a one-line “OK” produces 1440 emails. Two options:
- Redirect output to a file or
/dev/nullwhen the job’s stdout/stderr isn’t useful:* * * * * /path/to/script >> /var/log/myjob.log 2>&1. - Only output on error, so cron mails only when something’s wrong: have the script print nothing on success and a clear error on failure. (cron mails by default if anything is written to stdout or stderr.)
The second is the better hygiene — silence on success, noise on failure.
Why * * * * * looks suspicious in a code review
Reviewers see * * * * * and ask: does this need to be that frequent, and is it overlap-protected? A surprising fraction of every-minute crons could be every-5-minutes without anyone noticing the latency change. Consider whether you actually need it.
For lower frequency, see cron every 5 minutes — almost always the right alternative for “I want it to feel responsive.”
Common pitfalls
- No overlap protection. Discussed above. The single biggest issue.
- Heavy job starts. A
* * * * *job with a slow startup (loading a full Python venv, JIT-compiling a large module) burns more time on startup than work. Move the startup cost into a long-running daemon and use cron only as a heartbeat. - Misaligned cron daemon load. Many
* * * * *jobs all fork at the top of every minute. The daemon spends ~100ms forking everything; the system has a 100ms spike. Stagger if many jobs share infrastructure. - Unbounded log output. A 1-line log per minute is 1440 lines per day, ~525,600 per year. Without rotation, fills disk. Ensure log rotation is set up.
- Forgetting the schedule when changing the script. A
* * * * *script with a regression runs 1440 times before someone notices. Use staging cron schedules for new jobs (every 15 minutes) until they’re proven, then promote to every-minute.
For less frequent schedules, see cron every 5 minutes, cron every 15 minutes, cron every hour. For full syntax, see cron expression generator.