135

It was recently pointed out to me that an alternative to cron exists, namely systemd timers.

However, I know nothing about systemd or systemd timers. I have only used cron.

There is a little discussion in the Arch Wiki. However, I'm looking for a detailed comparison between cron and systemd timers, focusing on pros and cons. I use Debian, but I would like a general comparison for all systems for which these two alternatives are available. This set may include only Linux distributions.

Here is what I know.

Cron is very old, going back to the late 1970s. The original author of cron is Ken Thompson, the creator of Unix. Vixie cron, of which the crons in modern Linux distributions are direct descendants, dates from 1987.

Systemd is much newer, and somewhat controversial. Wikipedia tells me its initial release was 30 March 2010.

So, my current list of advantages of cron over systemd timers is:

  1. Cron is guaranteed to be in any Unix-like system, in the sense of being an installable supported piece of software. That is not going to change. In contrast, systemd may or may not remain in Linux distributions in the future. It is mainly an init system, and may be replaced by a different init system.

  2. Cron is simple to use. Definitely simpler than systemd timers.

The corresponding list of advantages of systemd timers over cron is:

  1. Systemd timers may be more flexible and capable. But I'd like examples of that.

So, to summarise, here are some things it would be good to see in an answer:

  1. A detailed comparison of cron vs systemd timers, including pros and cons of using each.
  2. Examples of things one can do that the other cannot.
  3. At least one side-by-side comparison of a cron script vs a systemd timers script.
6
  • 5
    "Cron is guaranteed to be in any Unix-like system. That is not going to change." – I would strongly debate this. While historically cron has often been included in the base setup of Unix installations, on most systems today it's simply an arbitrary optional software package among others. In fact, there are several popular cron alternatives around (e.g. anacron, fcron, jobber) which may be preferable to cron. cron's functionality is not essential for a system's operation the way systemd or init is, so if you're concerned about current and future portability, I'd rather not place my bets on it.
    – Guido
    Apr 23, 2016 at 13:52
  • 2
    @Guido I just meant that it is guaranteed to be available for installation. I didn't men to say it was guaranteed to be installed on any given Unix-like system, though this is probably the case most of the time. On Debian, at least, cron has priority important, though it doesn't try very hard to stop me from removing it. The only thing my system has that actually depends on it is munin, which is a little surprising. Apr 23, 2016 at 14:39
  • 8
    That's quite a list of things you want in an answer. I think maybe you should spend some time learning the tools yourself and see if you can formulate those answers on your own, and if you have specific things you don't understand, ask them here.
    – larsks
    Apr 23, 2016 at 14:56
  • 2
    @larsks It's intended as a reference. In case that wasn't already clear. Apr 23, 2016 at 15:09
  • Regarding “one side-by-side comparison of a cron script vs a systemd timers script”: could you hand out at least one use case? Jan 26 at 4:00

4 Answers 4

75

Here are some points about those two:

  1. checking what your cron job really does can be kind of a mess, but all systemd timer events are carefully logged in systemd journal like the other systemd units based on the event that makes things much easier.

  2. systemd timers are systemd services with all their capabilities for resource management, IO CPU scheduling, ...
    There is a list :

    • systemcall filters
    • user/group ids
    • membershipcontrols
    • nice value
    • OOM score
    • IO scheduling class and priority
    • CPU scheduling policy CPU
    • affinity umask
    • timer slacks
    • secure bits
    • network access and ,...
  3. with the dependencies option just like other systemd services there can be dependencies on activation time.

  4. Units can be activated in different ways, also combination of them can be configured. services can be started and triggered by different events like user, boot, hardware state changes or for example 5mins after some hardware plugged and ,...

  5. much easier configuration some files and straight forward tags to do variety of customizations based on your needs with systemd timers.

  6. Easily enable/disable the whole thing with:

    systemctl enable/disable 
    

    and kill all the job's children with:

    systemctl start/stop
    
  7. systemd timers can be scheduled with calenders and monotonic times, which can be really useful in case of different timezones and ,...

  8. systemd time events (calendar) are more accurate than cron (seems 1s precision)

  9. systemd time events are more meaningful, for those recurring ones or even those that should occur once, here is an example from the document:

    Sat,Thu,Mon-Wed,Sat-Sun → Mon-Thu,Sat,Sun *-*-*00:00:00
      Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:00
                    Wed *-1 → Wed *-*-01 00:00:00
            Wed-Wed,Wed *-1 → Wed *-*-01 00:00:00
                 Wed, 17:48 → Wed *-*-* 17:48:00 
    
  10. From the CPU usage view point systemd timer wakes the CPU on the elapsed time but cron does that more often.

  11. Timer events can be scheduled based on finish times of executions some delays can be set between executions.

  12. The communication with other programs is also notable sometimes it's needed for some other programs to know timers and the state of their tasks.

4
  • 3
    That's a good effort, thank you. However, more direct comparisons with cron would be helpful, including an example. Also, some of what you write is not completely clear, e.g. "from the CPU usage view point systemd timer wakes the CPU on the elapsed time but cron does that more often." May 5, 2016 at 8:49
  • Hello, @F.sb ! Your answer seems to imply that you can schedule jobs using different time zones. Is this correct? How would you do that? It would be a significant advantage over standard implementations of cron, but I couldn't find any info about it, except for man systemd.time which seems to contradict it: Non-local timezones except for UTC are not supported.
    – Tad Lispy
    May 24, 2017 at 15:48
  • The dependencies are handy. For example if the host backup runs as a systemd timer then you can use dependencies to ensure that a database export completes immediately prior to the backup.
    – vk5tu
    Nov 22, 2017 at 11:17
  • 3
    @jasper dear i use both of them based on my needs, and it's always your choice to choose one based on your needs, i just mentioned some facts based on docs and manuals.
    – FargolK
    Dec 6, 2017 at 9:30
25

Straight from the horse's mouth, so to speak: https://wiki.archlinux.org/index.php/Systemd/Timers#As_a_cron_replacement

An excerpt from the page above:

Benefits

The main benefits of using timers come from each job having its own systemd service. Some of these benefits are:

  • Jobs can be easily started independently of their timers. This simplifies debugging.
  • Each job can be configured to run in a specific environment (see systemd.exec(5)).
  • Jobs can be attached to cgroups.
  • Jobs can be set up to depend on other systemd units.
  • Jobs are logged in the systemd journal for easy debugging.

Caveats

Some things that are easy to do with cron are difficult to do with timer units alone.

  • Complexity: to set up a timed job with systemd you create two files and run a couple systemctl commands. Compare that to adding a single line to a crontab.
  • Emails: there is no built-in equivalent to cron's MAILTO for sending emails on job failure. See the next section for an example of setting up an equivalent using OnFailure=.
2
3

Let me pick up the POP3 example you recently mentioned in a comment. It is a good example, because POP3 can not notify the arrival of new mail. (For IMAP access I would not use a timer solution, because IMAP actually can notify!)

Cron

crontab -e

-e stands for edit. Caution: launching without options does not give help, but flushes all your existing cron jobs if you do not manage to get out of the editor without saving.—And that definitively means to lose work if you had existing jobs.

So, in the edit mode, add a line:

30 14,21 * * * mpop --quiet

which launches mpop 2:30pm and 9:30pm.

In theory you could also have edited /var/spool/cron/crontabs/username, but most crons would not notice and the directory permissions often do not allow direct access to the file.

Cron jobs are less joy to debug. More often than not you end up scheduling it every minute until you trust it and then set the frequency correctly.

Otherwise it is a pretty quick interface for job repetition.

These days, don’t be surprised when you have no cron daemon running. Package systemd-cron (at least on Debian) serves you systemd timers with a cron user interface: it translates the crontab line transparently for you and the command line tools are the same.—The other way around will probably never exist.

Systemd timer

loginctl enable-linger

has to be run once (and never again). It makes sure that the user mode systemd is launched on boot. Otherwise the first login would launch it.

systemctl --user edit --full --force mpop.service

You can also run just systemctl edit mpop.service to get successive errors and hints guiding you to the correct command line with options:

No files found for mpop.service.
Run 'systemctl edit --force --full mpop.service' to create a new unit.

Running the suggested command would reveal permission problems with writing the file and ask for a password to reload the system daemon.—At this point you should remember to add --user to talk to the user systemd instance. Note: you could also go for the system instance, but I’m not describing that here. It is similar.

Unlike with cron, you could really go directly for the file ~/.config/systemd/user/mpop.service, but you have to remember the path yourself. And in some cases systemd --user daemon-reload is needed. E.g. if the file is actually existing and loaded. systemd --user edit ... does a daemon-reload in any case so you don’t have to.

So, in the mpop.service file you add:

[Service]
ExecStart=mpop --quiet

You can test run this with systemctl --user start mpop. mpop is short for mpop.service here.

Check details with systemctl --user status mpop or the full output of past runs with journalctl --user -u mpop (-u is short for --unit).

With systemd, the timer is another unit which triggers the service unit.

Create one with:

systemctl --user edit --full --force mpop.timer

And save the following in the editor:

[Timer]
OnCalendar=*-*-* 14,21:30:00

[Install]
WantedBy=timers.target

The OnCalendar= can be written shorter. As the Unit= to active is not written explicitly, the service by the same name will be triggered.

Like the service (short lived), the timer (long living) will initially be off. The service is activated by the timer, so no worries here.

But what activates the timer?—This is where the [Install] section comes into play. It is related to the systemctl --user enable/disable ... and they all have very unfortunate names.

The section should be called [Hooks] and the commands ... hook/unhook .... Reasons:

  • the timer is already installed with the existence of the mpop.timer file
  • would reveal the relationship between the section and the commands
  • the enable command might not enable the unit if it is hooked to a siding unit or a non-existing one (you get a warning for the latter, though), but it will show as “enabled”.
  • the mpop.service unit has no [Install] section and enable/disable do nothing on it, it is shown as “static”, even though it is as “enabled” as it gets

Having that said, you can see that the WantedBy= hook mentions a well-known target, one which is started in normal circumstances and the one supposed to be used for timers.

Use systemctl --user list-dependencies default.target now and after the following steps to see what happens around timers.target:

systemctl --user enable mpop.timer  # hooks it into the timers.target
systemctl --user start timers.target  # this or reboot

I consider executing start on timers.target instead of mpop.timer (both work) better practice. It helps detecting spelling mistakes in the [Install] section of the timer unit and follows closer the execution path on reboots.

0

“systemd timers” vs “cron” is like to “systemd“ vs “SysV init”.

You know the endless debate around systemd? Often very subjective, very emotional. Most arguments for and against it, valid and not, could be repeated here almost verbatim. Including technical aspects and aspects which are technical at first glance.

I remember the days when there was no way for system users to launch a daemon, except via cron: a script, run every minute, doing 99.9% nothing, just to launch a long-running process in case the machine got rebooted.

These days, it is more a matter of which cron you run to determine how good the use case I just described is covered (i.e. @reboot timers). (Or e.g. the ability to run missed jobs...)

Systemd has you covered here as well, even without its timers! – Your use case might also be best solved with neither cron nor timers. Your use case might best be solved with the hook your system offers.

Update: OP added the POP3 example.—Now I’m able to answer the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.