Cron – Scheduling a job to run every 23 minutes

cronposix

There are cases when I need to run a scheduled job in more complex way that Cron is able to provide. Say, to schedule a job to run every 23 or 65 minutes.

In the latter case it can be worked around by adding multiple Cron entries to run the same line. In the first case the number of lines to add becomes too much.

Three obvious solutions:

  • run the process every minute; use the job's its own logic to deduce when it should actually run and keep its state somewhere (say, in a file)
  • use "sleep" within script to pause for specified amount of time and keep it running using something like Supervisor
  • use any utility able to run a process periodically with arbitrary periods (such as a monitoring utility) and launch the task with it

but they all are inconvenient under certain circumstances.

Is there a smarter replacement for Cron, available at least for POSIX systems, able to use arbitrary schedules?

Best Answer

To run a job every 23 minutes the following won't work:

*/23 * * * * /some/command

As that will run on 00:00, 00:23 , then 23 minutes later again on 00:46 and then again on 01:00 which is 14 minutes later and not quite every 23 minutes.

The reason for that is that the / in */23 is not a mathematical "divide by" and does not match "whenever the number of minutes (since when? Midnight?) is a multiple of 23" .

*/23 is rather an "increments of". This tells cron to match every 23rd item (/23) from the set of minutes 0 1 2 3 4 5 6 7 8 9 10 11 ... 59 (for which * is the shorthand) i.e. minutes 0, 23 & 46.

That incremental behaviour also allows you to shift the off-set i.e. by starting the range at 1 rather than 0:

1-59/23 * * * * /some/command 

That job will now run every hour, 1 minute past, 24 minutes past and again 47 minutes past the hour.


I concur with your assessment that for odd schedules cron syntax is insufficient.

Cron is a very simple time driven scheduler.

I assume you probably want to run your job every 23 minutes because that is the the sum of the runtime of your batch job(s) and an added a bit of safety margin?

You choice is either simplify your scheduling needs such that they can work with cron, i.e. run your job every 30 minutes, or abandon that notion of time driven scheduling almost completely and investigate an event driven scheduler.

With an event driven scheduler the completion of one batch is the trigger to automatically start the next batch, optionally without delays and without running the risk you have with a time based scheduler that a batch starts before a previous batch has completed.

Wikipedia provides a comprehensive list of Job scheduler software or workload automation as many vendors like to call their products.

Related Topic