LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

How To Set Up Cron On Your VPS

In this tutorial, we will see how to set up repetitive tasks on your VPS. You may want to automate system maintenance or administration so that you

  • download email every day,
  • download weekly new songs from the Internet,
  • erase files that you do not need any more,
  • daily backup your databases or data,
  • update your system with the latest security patches,
  • check your disk space usage,
  • send emails

and so on. The command that will do all that for you is cron and the tasks are called cron jobs. Many popular software packages, will either ask you to fill in cron details or, like Drupal and Magento, will install cron jobs on their own.

What We Are Going To Cover

  • Definition of crontab
  • How to add cron command to a crontab file
  • Saving the output of cron jobs
  • Structure of crontab commands
  • Start, stop, restart cron on Centos & Ubuntu / Debian
  • Editing crontab file in Ubuntu, Debian, and Centos
  • Crontab restrictions
  • General format of cron commands
  • Crontab variables
  • Examples of cron jobs


  • You will need ability to SSH into your VPS as a root.
  • You should also have one non-root user with sudo capabilities, at your disposal.
  • We use nano as our text editor. It will come preinstalled on Ubuntu and Debian. On Centos, install it with this command:
yum install nano

Press y twice to finish the installation.

What Is crontab

crontab, which is short for cron table, is a configuration file that defines shell commands to run periodically on a given schedule.

Cron may be system-wide or on a single user basis so there will be two kinds of crontabs, one for root user and the others for individual users. System-wide crontab will contain column for a particular user name, while crontabs for individual users will not.

On all three systems, the system-wide crontab is at /etc/crontab. You can edit cron jobs directly from this file but you actually shouldn’t. True automation will come only if each user has its own set of crontab files.

On CentOS, crontab files are stored in the /var/spool/cron directory while on Debian and Ubuntu, crontab files are stored in the /var/spool/cron/crontabs directory.

Crontab File Locations in Centos

Here are the locations for cron jobs:


/var/spool/cron/ contains a crontab file for each user who is using crontab.

Log files for cron runs can be found at the /var/log/cron.

The Contents of a System-wide crontab File on Ubuntu

Use this command to quickly see the contents of the crontab file:

cat /etc/crontab

Lines starting with # are comments.

Let’s analyse the contents of crontab file.

Crontab Variables

Lines such as


contain cron variables.

SHELL – it is possible to choose the shell that cron will run from. The default is /bin/sh.

PATH command, to denote where the system should look up when executing cron commands (see below). If PATH is blank, the entire path to the command must be explictly stated in the command itself.

HOME Normally, cron would execute the command from the user’s home directory. You can change the HOME variable to point to another directory.

MAILTO For each event, cron sends email notifications to the owner of the crontab. Specify a comma separated list of all the email addresses you want the notifications to be sent to. Put MAILTO=”” to deliver no mail at all.

Here is an example of a cron job with all these variables:


*/1 * * * * command

This command would execute every minute.

Cron Commands Explained

Columns in cron commands have the following meaning:

  • m – minutes during the hour, from 0 to 59. Number 17 in this column means crontab will perform an action on every 17th minute of the hour.
  • h – hours during the day, from 0 to 23. Number 6 here would mean some action would be performed every six hour during the day.
  • dom – date of month, from 0 to 31.
  • mon – month in year, from 0 to 11. Instead of numbers we can use jan, feb, mar, apr etc.
  • dow – day of week, from 0 to 6, where 0 is Sunday and 6 is Saturday. On some systems, 7 can mean Sunday as well.

It is also possible to use

Operator Values In Columns

* Asterisk means any value or always. An asterisk symbol in the Minutes field will perform the each minute.

, Comma specifies a list of values for repetition. For example, if you have 1,13,15 in the Hour field, the task will be run at 1 am, 1 pm and 3 pm.

Hyphen specifies a range of values. If you have 1-5 in the Month field, the task will run every month from January to May.

/ Slash specifies values that will be repeated over a certain interval between them. For example, if you have */4 in the Minutes field, the action will be performed every four minutes. The same effect would be to have had specified values of 0,4,8,12,16,20. You can also put a range of values before the slash. For example, 1-30/10 is the same as 1,11,21.

Crontab Restrictions

Imagine you are the system administrator and one of your users has started sending email marketing campaigns at the rate of 20,000 messages per hour. That may lead to poor experience for other users of your VPS, or you may want that user to just start paying more for the convenience. Or, you can restrict his crontabs on a user per user basis. That is where files /etc/cron.deny and /etc/cron.allow come into play. They contain a list of user names, one user name per row.

The /etc/cron.deny file exists by default and in the beginning it is empty. That means that all users of the system can use cron jobs. User with names listed in that file will not be able to use cron at all.

The counterpart file is /etc/cron.allow – only the users with names in it will be allowed to use cron.

If neither file exists, and depending on other system parameters, either only the super user will be able to use cron jobs, or all users would be able to use cron jobs.

Using crontab Command on Ubuntu

Here is a handy command:

crontab -e

It asks to decide upon an editor and we choose nano.

Once in it, we see the crontab file contents:

Editing crontab File in Debian

The command is the same:

crontab -e

Choose nano amongst eight different editors that Debian offers:

You will end up in the same content as for Ubuntu, so we won’t repeat the image.

Editing crontab File in Centos

Use nano to edit the crontab file directly:

sudo nano /etc/crontab

and the contents of the crontab file are different:

Each time you change a crontab, you will need to restart the cron utility. Here are the relevant commands.

Start, Stop, and Restart cron on Ubuntu / Debian

sudo service cron status
sudo service cron start
sudo service cron stop
sudo service cron restart

Start, Stop, and Restart cron On Centos

service crond status
service crond stop
service crond start
service crond restart

Structure Of crontab Commands

Here are the parameters of the crontab command:

crontab -eEdit crontab file, or create one if it doesn’t already exist.
crontab -l  Display crontab file contents.
crontab -r Remove current crontab file.
crontab -i Remove current crontab file with a prompt before removal.
crontab -u Edit other user’s crontab file. Must be run with system administrator privileges.

Examples of cron Commands

Schedule a backup script to run every day at 5:30 AM:

30 5 * * * /path/to/script/backup-script.sh

To schedule the backup on the first day of each month at 8 PM:

0 18 1 * * /path/to/script/backup-script.sh

It is possible to use several macros to start events in the beginning of hour, day, week, and month.

@hourly path/to/script/script.sh
@daily path/to/script/script.sh
@weekly path/to/script/script.sh
@monthly path/to/script/script.sh
@reboot path/to/script/script.sh

The last line, with @reboot, will execute after server reboot.

Saving the Output of cron Jobs

In general, the script we execute as cron jobs will generate some output. We can save it log files, like this:

0 3,11,16 * * tue,sat path/to/script/script.sh > /path/to/logs/backup.log 2>&1

That command will execute on Tuesdays and Saturdays, at 3 AM, 11 AM and 16 PM and will save the output to a file called backup.log at the address /path/to/logs.

If we do not want to record any output, the command can look like this:

0 3,11,16 * * tue,sat path/to/script/script.sh > /dev/null 2>&1

How To Add cron Command To a crontab File

We simply open the crontab file with nano, and enter one or more of the above commands in the end. Here is crontab file found in the fresh server install in Centos:

sudo nano /etc/cron.d/0hourly

Now enter the line shown above and you’ll get:

Save and close the file and that restart crond in this case. Of course, in real life you would put your own script address instead of path/to/script/script.sh.

What Can You Do Next

Take a long and hard look at the way you are using your VPS and then surf around. You will find many repetitive tasks that you would like to automate so start using cron and crontab files as much as you can!

Dusko Savic is a technical writer and programmer.


1 Comment

  1. Erik Ashfolk:

    Hi . great . Thank you.

    Below is Tested on Debian 9.9 stretch:

    Suppose your VPS provider has allotted you a /64 IPv6 NET/range 2001:DB8:1:101::/64 ,
    and you have to add custom/few IPv6-addresses from that NET/range with your network-interface-card eth0, for your VPS related usage.

    So you have to use commands like this to complete the setup of IPv6 net-stack:
    [code]root@vps:~# /sbin/ifconfig eth0 inet6 add 2001:DB8:1:101:0:e24a:1316:11e/64
    root@vps:~# /sbin/ip -r route add 2001:DB8:0001:0000:0000:0000:0000:0001 dev eth0
    root@vps:~# /sbin/ip -r route add default via 2001:DB8:0001:0000:0000:0000:0000:0001[/code]

    You may add those commands simply + directly in (bottom of) your “/etc/network/interfaces” file like this:
    [code]up /sbin/ifconfig eth0 inet6 add 2001:DB8:1:101:0:e24a:1316:11e/64
    post-up /sbin/ip -r route add 2001:DB8:0001:0000:0000:0000:0000:0001 dev eth0
    post-up /sbin/ip -r route add default via 2001:DB8:0001:0000:0000:0000:0000:0001[/code]

    your “/etc/network/interfaces” should (previously) have (or look like) these/similar settings:
    [code]# The loopback network interface
    auto lo
    iface lo inet loopback
    iface lo inet6 loopback

    # The primary network interface
    auto eth0
    iface eth0 inet static
    address 192.0.X.Y

    gateway 192.0.X.1

    iface eth0 inet6 static
    address 2001:DB8:1:101::
    netmask 64

    gateway 2001:DB8:0001:0000:0000:0000:0000:0001[/code]

    IF AFTER a REBOOT your network settings remain (as you have wanted) then no need to do/add cron jobs, otherwise follow…

    Some VPS with some Linux/Unix does not easily allow to update/add commands directly in the “/etc/network/interfaces”

    Create a bash script file “my-vps-net-ipv6-interfaces.sh” inside the /etc/network/ folder:
    [code]root@vps:~# cd /etc/network/
    root@vps:~# nano /etc/network/my-vps-net-ipv6-interfaces.sh[/code]
    Add below contents inside the bash script file “my-vps-net-ipv6-interfaces.sh”:
    [code]#!/usr/bin/env bash
    /sbin/ifconfig eth0 inet6 add 2001:DB8:1:101:0:e24a:1316:11e/64
    /sbin/ip -r route add 2001:DB8:0001:0000:0000:0000:0000:0001 dev eth0
    /sbin/ip -r route add default via 2001:DB8:0001:0000:0000:0000:0000:0001[/code]
    after typing (or copy-paste + modify to suit with your actual info for) the above , save the content in a file press \^O , press “Enter” to Save , press \^X to exit from nano . the symbol \^ means “Control”-button.

    Make the script executable:
    [code]root@vps:~# chmod 744 /etc/network/my-vps-net-ipv6-interfaces.sh[/code]

    Create a CRON JOB, so that after each reboot, your network-settings are auto applied/updated/loaded:
    [code]root@vps:~# cd /etc/cron.d/
    root@vps:~# nano runOnReboot[/code]
    add below content into “runOnReboot” file:
    [code]# this is “runOnReboot” file, to load+start cron jobs immediately after reboot
    @reboot root /bin/bash /etc/network/my-vps-net-ipv6-interfaces.sh[/code]
    after typing (or copy-paste + modify to suit with your actual info for) the above , save the content in a file press \^O , press “Enter” to Save , press \^X to exit from nano.

    Now reboot & test:
    [code]root@vps:~# ip -6 route
    2001:DB8:1::1 dev eth0 metric 1024 pref medium
    2001:DB8:1:101::/64 dev eth0 proto kernel metric 256 pref medium
    fe80::/64 dev eth0 proto kernel metric 256 pref medium
    default via 2001:DB8:1::1 dev eth0 metric 1024 pref medium
    root@vps:~# ping6 2606:4700:4700::1111 -c4
    PING 2606:4700:4700::1111(2606:4700:4700::1111) 56 data bytes
    64 bytes from 2606:4700:4700::1111: icmp_seq=1 ttl=59 time=2.11 ms
    64 bytes from 2606:4700:4700::1111: icmp_seq=2 ttl=59 time=2.18 ms
    64 bytes from 2606:4700:4700::1111: icmp_seq=3 ttl=59 time=2.04 ms
    64 bytes from 2606:4700:4700::1111: icmp_seq=4 ttl=59 time=2.31 ms

    — 2606:4700:4700::1111 ping statistics —
    4 packets transmitted, 4 received, 0% packet loss, time 3003ms
    rtt min/avg/max/mdev = 2.043/2.163/2.313/0.115 ms
    root@vps:~# host 2606:4700:4700::1111 domain name pointer one.one.one.one.
    root@vps:~# ping6 one.one.one.one -c4
    PING one.one.one.one(one.one.one.one (2606:4700:4700::1001)) 56 data bytes
    64 bytes from one.one.one.one (2606:4700:4700::1001): icmp_seq=1 ttl=60 time=2.03 ms
    64 bytes from one.one.one.one (2606:4700:4700::1001): icmp_seq=2 ttl=60 time=4.68 ms
    64 bytes from one.one.one.one (2606:4700:4700::1001): icmp_seq=3 ttl=60 time=2.07 ms
    64 bytes from one.one.one.one (2606:4700:4700::1001): icmp_seq=4 ttl=60 time=2.11 ms

    — one.one.one.one ping statistics —
    4 packets transmitted, 4 received, 0% packet loss, time 3004ms
    rtt min/avg/max/mdev = 2.038/2.728/4.689/1.133 ms
    root@vps:~# ping6 2001:DB8:1:101:0:e24a:1316:11e -c4
    PING 2001:DB8:1:101:0:e24a:1316:11e(2001:DB8:1:101:0:e24a:1316:11e) 56 data bytes
    64 bytes from 2001:DB8:1:101:0:e24a:1316:11e: icmp_seq=1 ttl=64 time=0.017 ms
    64 bytes from 2001:DB8:1:101:0:e24a:1316:11e: icmp_seq=2 ttl=64 time=0.028 ms
    64 bytes from 2001:DB8:1:101:0:e24a:1316:11e: icmp_seq=3 ttl=64 time=0.015 ms
    64 bytes from 2001:DB8:1:101:0:e24a:1316:11e: icmp_seq=4 ttl=64 time=0.027 ms

    — 2001:DB8:1:101:0:e24a:1316:11e ping statistics —
    4 packets transmitted, 4 received, 0% packet loss, time 3063ms
    rtt min/avg/max/mdev = 0.015/0.021/0.028/0.008 ms

    June 26, 2019 @ 9:50 pm | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

Your email address will not be published. Required fields are marked *