25

Is the cron job scheduler really precise?

I mean, I need a script to run every night the latest possible, BUT before 00:00 of the next day.

I'd ideally run a cron job at 23.59 (or 11:59 pm), but will the system be really precise? Since a second does matter, should I set the cron job to 23:58 to leave it some time?

4
  • 13
    Why do you have these requirements? I have a feeling there will be a better way to do whatever you're really trying to do, and you might as well ask about that. (It'll take a bit more effort than just scheduling a cron job, but perhaps not much more.)
    – David Z
    Sep 9, 2015 at 14:20
  • I used to use an old dumb cron with a precision of 10 minutes.
    – joshudson
    Sep 9, 2015 at 16:13
  • 7
    Your requirement looks not very reliable to me. What do you do if your system has high load around midnight. Unless you have a RT system, you can not guarantee anything. Sep 9, 2015 at 18:10
  • Consider that even if you manage to procure a server that's always available and can always complete your job in under a second, there are still things that can go wrong. For example, your clock may begin to drift without your realizing. This is really, really fragile and I agree with the above comments that the system needs to change. Sep 10, 2015 at 8:44

4 Answers 4

24

What cron can guarantee is that your job will start no sooner than the specified time (subject to precision of the system clock). But there is no way to give you any guarantee about the termination time of the job. It will depend on a lot of factors:

  • How loaded is the system
  • What does the job do
  • Slowness due to hardware issues
  • Slowness due to networking issues (assuming the job depends on networking)

My recommendation is to change your design such that a specific completion time is not a requirement.

6
  • 1
    The easiest way to do this is probably to have the job that is started through cron create a file to indicate it is running that is deleted whenever the job exits (successfully or unsuccessfully), and then the next job (assuming that is the purpose) wait until the file disappears before it does anything.
    – user
    Sep 9, 2015 at 13:45
  • @MichaelKjörling You should use a directory, rather than a file, as checking for a file and then creating it is not atomic.
    – 8bittree
    Sep 9, 2015 at 17:18
  • 1
    @8bittree you can use flock too if it's available.
    – user9517
    Sep 9, 2015 at 20:04
  • 1
    @MichaelKjörling But why bother with the maybe okay case when the correct case is also simpler?
    – 8bittree
    Sep 9, 2015 at 20:07
  • 4
    @8bittree If you use O_CREAT and O_EXCL flags it will be atomic as long as the file is on a local file system.
    – kasperd
    Sep 10, 2015 at 7:49
15

I suppose this depends on your cron daemon, but the documentation and the standard indicate that if you specify minutes, the job will execute at the specified minute.

See:

Be aware that your script will be started when the clock ticks over to the correct time, but will finish some time after that.

1
  • I have a virtual server with very low load, and yet a cron that is set to run every minute will start sometimes at 0s, 1s, 2s, sometimes up to 17s. My guess is that cron can be less accurate on a virtual server, as other process outside of that server can affect the availability of resources such as CPU.
    – Liam
    Nov 19, 2019 at 18:16
9

Usually cron will start at 23:59:00, scan all your crontab files, filter out those who are relevant for 23:59 and then start them. Scanning this files is very fast, because there are not many of them and they all only include a few lines. So usually, the cronjobs start at 23:59:00 or 23:59:01 There are sure ways to intentionally slow down this process. (add millions of lines to the crontab, for example). If the system is totally overloaded, this also won't work that fast.

Also, this is obviously implementation dependent.

If you need very exact start times, you are better off creating a programm that sleeps until the time you want and then runs (e.g. using c++11). But on a non real-time OS, this also won't be exact! Also the clock of the PC doesn't know the exact time!

In all cases, this only makes sure the program starts at (more or less) the time you want. There cannot be any guarantee that the program ends successful until a given time, so I strongly believe you should change something on that requirement.

1
  • 2
    I believe the crontabs are held in memory - if you edit the files behind crontab directly (instead of crontab -e, which notifies cron when complete), the changes won't take effect. cron has oodles of downtime to work out what jobs are coming up, it can "sleep" until the exact second the job is due to run. Sep 10, 2015 at 2:07
1

It depends from your overall script execution time and precision of server time.

59 23 * * * /some/script/file.sh

will launch your script exactly at 23:59, but, if you have some commands which works a long time, part of script may be executed after midnight.

3
  • exactly at 23:59, so it can be from 23:59:00 to 23:59:59?
    – A.L
    Sep 9, 2015 at 12:16
  • 2
    You do not have seconds in normal cron. To get those extra 59 seconds you have to add a 'wait(59)' at the top of your code. Sep 9, 2015 at 13:27
  • 4
    @A.L in practice, I've always seen it run at xx:xx:00 or xx:xx:01, but on a heavily-loaded system there aren't and can't be any promises.
    – hobbs
    Sep 9, 2015 at 21:05

You must log in to answer this question.