How to Schedule Cron Jobs at Custom Intervals
Crontab controls what runs and when. Each crontab entry has this format:
.---------------- minute (0-59)
| .------------- hour (0-23)
| | .---------- day of month (1-31)
| | | .------- month (1-12) OR jan,feb,mar,apr ...
| | | | .---- day of week (0-6) (Sunday=0 or 7) OR sun,mon,tue ...
| | | | |
* * * * * command to be executed
To edit your user’s crontab:
crontab -e
By default, cron uses /bin/sh. Override it by adding this at the top of your crontab file:
SHELL=/bin/bash
Check crontab(5) and cron(8) man pages for full details. For complex scheduling needs, consider systemd timers as an alternative.
Method 1: Step Values
Crontab supports step syntax with /. The expression 1-9/2 equals 1,3,5,7,9.
For jobs every two months at 1:00 AM on the 1st:
0 1 1 */2 * /path/to/command
For jobs every two days at 1:00 AM:
0 1 */2 * * /path/to/command
Important caveat: This isn’t always “exactly” every N time units. */2 on day-of-month means “every other day that exists in the month,” and */2 on month means “every other month in the year.” If you need precise intervals (e.g., exactly 48 hours), use Method 2 or 3.
Method 2: Conditional Test in the Command
Since cron executes shell code, you can run a job frequently and guard the actual command with a test condition.
For a job every 2 days (exactly 172,800 seconds), at 1:00 AM daily:
0 1 * * * [ $((($(date +%s) / 86400) % 2)) -eq 0 ] && /path/to/command
This calculates days since Unix epoch (1970-01-01 00:00:00 UTC), divides by 2, and only runs when the remainder is 0.
For a job every 5 months starting from March 2016, at 1:00 AM:
0 1 1 * * [ $((($(date +%Y) - 2016) * 12 + $(date +%m) - 3) % 5)) -eq 0 ] && /path/to/command
This calculates months elapsed since March 2016 and runs only when divisible by 5.
For a job every 2 weeks at 2:00 AM on Tuesday:
0 2 * * 2 [ $((($(date +%s) / 604800) % 2)) -eq 0 ] && /path/to/command
Where 604800 = seconds in a week.
Method 3: State File Tracking
Create a wrapper script that uses a marker file on disk to track whether the job ran on its last invocation.
Example script at /home/share/bin/backup-job:
#!/bin/bash
mark_file="$HOME/.backup-job-marker"
if [ -e "$mark_file" ]; then
rm -f "$mark_file"
# Run the actual job
/path/to/backup/command
else
touch "$mark_file"
exit 0
fi
First run: marker doesn’t exist, so it’s created and the script exits.
Second run: marker exists, so it’s removed and the command runs.
Third run: repeats cycle.
If this script runs weekly via cron, the job executes every two weeks.
Add to crontab:
0 2 * * 2 /home/share/bin/backup-job
This runs your backup at 2:00 AM every other Tuesday.
You can extend this approach with timestamps or other state:
#!/bin/bash
mark_file="$HOME/.job-marker"
days_between=14
if [ -e "$mark_file" ]; then
last_run=$(stat -c %Y "$mark_file")
now=$(date +%s)
if [ $(((now - last_run) / 86400)) -ge "$days_between" ]; then
/path/to/command
touch "$mark_file"
fi
else
touch "$mark_file"
fi
This ensures the command runs at most once per 14-day window.
Comparison
| Method | Pros | Cons |
|---|---|---|
| Step values | Simple, readable | Not exact time intervals |
| Conditional test | Precise intervals, inline | Complex syntax, harder to debug |
| State file | Flexible, handles edge cases | Requires script file, disk I/O |
Choose based on your accuracy requirements and complexity tolerance. For production backup jobs or critical infrastructure work, Method 2 or 3 offers better guarantees.

Wouldn’t 0 2 * * 2 just run it 2am EVERY Tuesday?
I think what your looking for is:
0 2 * * 2/2
or
0 2 * * Tue/2
You are right. The most updated instruction is at the beginning of the post.
The “poor man’s” solution here works actually — the invoked script is invoked every Tue but it records its state and does nothing every next time it is invoked.
aaah I see, cool thanks man :-)
Your explanation defeats the purpose of CRON. I could implement my own logic in code (every two weeks) and I only need cron to run every minute … So please correct your script.
Hi Eric, I have a request to make the job run in each alternative monday usually twice a month….
What’s the instruction for that??
This is easy to do in your crontab file with no external scripting:
0 2 * * tue [ `expr $(date ‘+\%U’`) % 2` -eq ‘0’ ] && /home/share/bin/real-xen-bak
This will only work if your “date” command understands the “%U” format, which gives the week-of-the-year. The “date” command on most *NIX systems will understand this, as “date” uses the C-library’s “strftime” function which specifies “%U” as the format specifier for week-of-year.
Interesting script.
The most easy method as far as I find is the ranges-based one like */2 supported by cron. Please check the Update at the beginning of the post.
I was wondering if there was a way to schedule something, say every 5 months, that changes the month when it crosses a year boundary. For example I have the following cron expression :
0 1 1 15 3/5 ? *
Which, when I run it starting at the beginning of the year gives me these fire times :
1. Sunday, March 15, 2015 1:01 AM
2. Saturday, August 15, 2015 1:01 AM
3. Tuesday, March 15, 2016 1:01 AM
4. Monday, August 15, 2016 1:01 AM
5. Wednesday, March 15, 2017 1:01 AM
Notice that if it were truly scheduling every 5 months, starting on the 3rd month, I would expect it to schedule in March 2015, August 2015, January 2016, June 2016, etc
Is this not the correct cron expression, or is there something I’m missing?
Hi Quenten, that’s a good question. The ‘*/5’ for months in crontab means every 5 months in a year.
For your purpose, you may try:
I also updated the post with more details. Please check out.
hi, how do we do it if we want it to run every alternate Tuesday at 0800?
0 8 * * 2/2
thanks,
You may use
0 8 * * 2 [[ $((($(date +%s) / 604800) % 2)) == 0 ]] && /path/to/your/cmdIt is invoked every Tuesday at 0800. However, your command will be executed only if the number of weeks since epoch is even.
I would like to run every 15days then how to write it.
Brilliant. Too bad we are tie with epoch and hv to be restrict to even, so if there is 5 Tuesday in a month, it will only run on the 2nd and 4th week. But its good enough at the moment :)
This will work with all Centos or only certain version? we are running on version 7.
p/s – how do you get the the 604800? its too small for minutes and too little if for seconds
thanks,
A more complex test condition may be used if you want to run it on 2nd and 4th Tuesdays in a month.
I believe this works on modern cron including those from CentOS 7. But please test it before deploying it into production.
604800 is 60 * 60 * 24 * 7. It is the number of seconds in a week.
Everyone,
I also have a script to run every 2nd and 4th Tuesday of each month for 2017. I use the following entries (starting June 13, 2017 to Dec 26, 2017). I know it is long, but it is easier to read and without the need for any date calculation.
Note: make sure that you do not specify the day of week (2); otherwise, cron will run on
BOTH on a specify day of the month AND on Tuesday of EVERY week.
I use this URL to validate
this URL to calculate: http://cron.schlitt.info/index.php?cron=30+3+13+6+*&iterations=10&test=Test
30 3 13 6 * myscript.sh
30 3 27 6 * myscript.sh
30 3 11 7 * myscript.sh
30 3 25 7 * myscript.sh
30 3 8 8 * myscript.sh
30 3 22 8 * myscript.sh
30 3 12 9 * myscript.sh
30 3 26 9 * myscript.sh
30 3 10 10 * myscript.sh
30 3 24 10 * myscript.sh
30 3 14 11 * myscript.sh
30 3 28 11 * myscript.sh
30 3 12 12 * myscript.sh
30 3 26 12 * myscript.sh
I also found another method for the same time period June 13 to Dec 26 of 2017, but prefer the 1st method as it is more clear to me. The 2nd method below requires calculate whether a Tues will be on even or odd week of the month.
30 3 * 6-8,11,12 2 [[ $(expr `date +\%W` \% 2) = 0 ]] && myscript.sh
30 3 * 9,10 2 [[ $(expr `date +\%W` \% 2) = 1 ]] && myscript.sh
Interesting. But it seems the crontab entries need to be refreshed each year if Tuesday is a hard requirement.
Thanks for sharing
How to run cron after 5th of every month and every alternate day at 12 am
How to run cron after 5th of every month and every alternate day at 12 am
You may consider a crontab to be invoked every alternate day at 12am with a “test statement” to check whether it is after 5th day.
how to run cron Tuesday night and run on every two weeks?
86400 seconds is every day, not every two days.
`% 2` for every two days.
* */3 * * tue runSomething.here
To run some thing here every 3 days always on tue* day, is it correct?
as from crontab manual.
So, a rule like
`0 0 */3 * 2 your_command`
*should* run at 0 o’clock every 3 days if it is Tuesday from the rule.
But the implementation may be different. I did not test it.
what should be the cron syntax to run a job twice a month ?
[md]A cron job like this may work: `0 0 1,15 * * /path/to/your/command`
Every day 1 and day 15 of a month, the command will run at 00:00.
[/md]
@ Eric ma,
I would like to run the cron every 15days interval I tried as below
00 21 */15 * *
But the result didn’t not satisfying the 15days interval condition.
Nxt at 2020-07-16 21:00:00
then at 2020-07-31 21:00:00
then at 2020-08-01 21:00:00
then at 2020-08-16 21:00:00
then at 2020-08-31 21:00:00
This can work for one month but in next Month it again triggers from 1st day of the month. Can you help to provide the condition to satisfy the requirement?
Sir, I have to write crontab:
Latest two day data must be present remaining past data will be clean the temp
How I have to do that
I would like to run the cron every 15days interval I tried as below
00 21 */15 * *
But the result didn’t not satisfying the 15days interval condition.
Nxt at 2020-07-16 21:00:00
then at 2020-07-31 21:00:00
then at 2020-08-01 21:00:00
then at 2020-08-16 21:00:00
then at 2020-08-31 21:00:00
This can work for one month but in next Month it again triggers from 1st day of the month. Can you help to provide the condition to satisfy the requirement?
Hello Basheer,
Can you please let me know if you able to find the solution for your condition.
I think a test statement is an easy way to implement.
Example: Let’s say a command needs to be executed every Thursday.
0 0 1-7,15-21 * * [ `date +\%u` = 4 ] && /path/to/command
Cron job pattern for alternate thursday
Trying to understand the syntax. If I wanted this to run every 85 days, is it just as simple as changing the 2 to 85?
0 1 * * * && /path/to/your/command