Cron Jobs & Scheduled Tasks

Automating System Maintenance Tasks with Cron and Anacron

By the Domain India teamPublished 8 min read
Knowledge base article
Contents (8 sections)

Backups, log clean-ups, certificate checks and update reports are jobs nobody should run by hand. On Linux you hand them to a scheduler: cron for exact times on a server that is always on, anacron for daily or weekly jobs that must still run after the machine was switched off, and systemd timers, which can do both. This guide shows how to use each one safely on a server you manage yourself.

Key takeaways

Use cron (crontab -e) for jobs at exact times on an always-on server, anacron (/etc/anacrontab) for daily, weekly or monthly jobs that must catch up after downtime, and a systemd timer with Persistent=true when you want both plus proper logging. Always use full paths, log the output, and stop overlapping runs with flock. On Domain India shared hosting you get cron through the control panel only, and the shortest effective interval is every 4 minutes.

1. Cron, anacron and systemd timers compared

ToolRuns jobsCatches up after downtimeWho can use it
cronAt an exact minute, hour, dayNo: a missed run is skippedEvery user (crontab) and root (/etc/cron.d)
anacronOnce every N days, weeks or monthsYes, shortly after the next bootRoot, system-wide
systemd timerAt exact times or intervalsYes, with Persistent=trueRoot, or users with systemd user services

On AlmaLinux and Rocky Linux, the cron service (cronie) already hands the jobs in /etc/cron.daily, cron.weekly and cron.monthly to anacron, so those folders catch up after downtime by default. On Debian and Ubuntu, anacron is a separate package, and many services now ship systemd timers instead of cron files.

2. Writing a cron job

Edit your own schedule with crontab -e. Each line is five time fields and a command:

text
# ┌ minute (0-59)
# │ ┌ hour (0-23)
# │ │ ┌ day of month (1-31)
# │ │ │ ┌ month (1-12)
# │ │ │ │ ┌ day of week (0-7, Sunday is 0 or 7)
# │ │ │ │ │
  30 2 * * * /home/deploy/bin/backup.sh >> /home/deploy/logs/backup.log 2>&1

That runs the backup at 02:30 every day and appends everything it prints, errors included, to a log file. Some patterns worth knowing:

text
*/15 * * * *   every 15 minutes
0 3 * * 0      03:00 every Sunday
0 9 1 * *      09:00 on the 1st of each month
@reboot        once, when the server starts

For a longer list of patterns, see the cron expression cheat sheet.

List your jobs with crontab -l. Be careful with crontab -r: it deletes every job for that user without asking. Keep a copy with crontab -l > ~/crontab.bak before big edits.

System-wide jobs go in a file under /etc/cron.d/, which takes an extra field for the user to run as:

text
# /etc/cron.d/certcheck
0 6 * * * root /usr/local/bin/check-certs.sh

3. Writing an anacron job

anacron doesn't use clock times. Each line in /etc/anacrontab says how often a job should run, how long to wait after anacron starts, a name, and the command:

text
# period(days)  delay(min)  job-id          command
1               10          db.dump         /usr/local/bin/db-dump.sh
7               20          logs.prune      /usr/local/bin/prune-logs.sh
@monthly        30          report.monthly  /usr/local/bin/monthly-report.sh

anacron records when each job last ran in /var/spool/anacron/. If the server was off when a job was due, the job runs after the next start, following its delay. On AlmaLinux and Rocky Linux, START_HOURS_RANGE and RANDOM_DELAY at the top of the file control when in the day catch-up jobs may run.

Useful commands, run as root:

bash
anacron -T        # check /etc/anacrontab for syntax errors
anacron -f -n     # force every job to run now, ignoring timestamps

Often the simplest route is to drop an executable script into /etc/cron.daily/ and let the system's existing anacron setup run it. On Debian and Ubuntu, run-parts skips files whose names contain a dot, so name it db-dump, not db-dump.sh.

4. The systemd timer alternative

On current distributions, a systemd timer gives you cron-style schedules, anacron-style catch-up and logs in the journal. It takes two files:

ini
# /etc/systemd/system/db-dump.service
[Unit]
Description=Nightly database dump

[Service]
Type=oneshot
ExecStart=/usr/local/bin/db-dump.sh
ini
# /etc/systemd/system/db-dump.timer
[Unit]
Description=Run db-dump nightly

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=5min

[Install]
WantedBy=timers.target

Enable it with systemctl enable --now db-dump.timer, list all timers with systemctl list-timers, and read the output with journalctl -u db-dump.service. Persistent=true makes a run missed during downtime happen at the next boot.

5. Habits that make scheduled jobs reliable

Use full paths
Cron runs with a minimal environment and a short PATH. Write /usr/bin/php, not php, and give scripts full file paths.
Log the output
Append output to a log file with >> file 2>&1, or rely on the journal for systemd timers. A job with no log fails silently.
Stop overlapping runs
Wrap long jobs in flock, for example flock -n /tmp/backup.lock /home/deploy/bin/backup.sh, so a slow run is not started twice.
Escape percent signs
In a crontab line, a bare % means a new line. Put a backslash before each % in date formats, or move the command into a script.
Test by hand first
Run the script as the same user, from the home folder, before you schedule it. Check its exit code.
Alert on failure
Have the script exit non-zero on errors and send an alert, or ping a monitoring URL only when it succeeds.

Keep scripts that hold passwords readable only by their owner (chmod 700), and put secrets in a separate file with chmod 600 rather than in the crontab line itself.

Check the server's time zone

Cron and anacron use the server's local time zone. Run timedatectl to see it before you schedule anything that must happen at a particular hour, and remember that systemd timers can take an explicit zone in OnCalendar.

6. Finding out why a job didn't run

  1. Is the scheduler running? systemctl status crond on AlmaLinux and Rocky Linux, or systemctl status cron on Debian and Ubuntu.
  2. Did it start? Read /var/log/cron on AlmaLinux and Rocky Linux, or journalctl -u cron on Debian and Ubuntu.
  3. Did it fail? Read your job's own log file. "command not found" means a missing full path; "permission denied" means the script isn't executable (chmod +x).
  4. Is the syntax right? Five time fields in a user crontab, six (with the user) in /etc/cron.d, and a newline at the end of the file.

7. Running scheduled jobs on Domain India

Shared hosting (cPanel and DirectAdmin). You add cron jobs from the control panel's Cron Jobs page, with no SSH needed. You can't use anacron, systemd timers or /etc/cron.d, because those are server-wide. Jobs run on Indian Standard Time. Jobs set to run every 1, 2 or 3 minutes are automatically changed to every 4 minutes, so 4 minutes is the shortest effective interval. The step-by-step guide is How to set up a cron job, and some PHP functions that scripts rely on are disabled on shared hosting; see PHP disabled functions.

VPS. A Domain India VPS is self-managed with full root access, so everything in this guide applies: crontabs, anacron, /etc/cron.d and systemd timers. The card shows the live price, excluding 18% GST.

VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details

Frequently asked questions

What is the difference between cron and anacron?

Cron runs jobs at exact times and skips a run if the machine was off at that moment. Anacron runs jobs once every so many days, weeks or months, and catches up on a missed run shortly after the next boot. Anacron is used for daily, weekly and monthly maintenance.

Should I use cron or a systemd timer?

Both work. Cron is simpler for a quick schedule. A systemd timer gives you logs in the journal, catch-up after downtime with Persistent=true, and dependency handling, which makes it the better choice for important system maintenance on a current Linux distribution.

Why does my cron job work by hand but not from cron?

Usually because cron runs with a minimal environment. Use full paths for every command and file, set any environment variables the script needs inside the script, and send the output to a log file to see the actual error.

Can I use anacron on Domain India shared hosting?

No. Anacron and systemd timers are server-wide and need root. On shared hosting you add cron jobs from the control panel's Cron Jobs page, and the shortest effective interval is every 4 minutes.

How do I stop a cron job from running twice at the same time?

Wrap the command in flock with a lock file, for example flock -n /tmp/job.lock /path/to/script.sh. If the previous run still holds the lock, the new run exits straight away.

What does crontab -r do?

It deletes every cron job for the current user without asking for confirmation. Save a copy first with crontab -l > ~/crontab.bak.

Ready to automate? Set up a job in your control panel with How to set up a cron job, compare VPS plans if you need root-level scheduling, or open a support ticket if a job on your hosting won't run.

Need full control of your scheduler?

Self-managed KVM VPS with full root access for cron, anacron and systemd timers.

See VPS plans

Ready when you are

Get cPanel hosting from ₹125/mo + GST

See plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Cron vs Anacron vs systemd Timers | Domain India