141

I am looking for a node job schedule that will allow me to schedule a number of tasks at different intervals. For instance,

  • call function A every 30 seconds
  • call function B every 60 seconds
  • call function C every 7 days

I also want to be able to start and stop the process.

So far, I have looked at:

  • later - the syntax confuses me, also apparently you cant schedule tasks beyond a month

  • agenda- seems the most promising, however I'm confused about the database functionality

  • timeplan - too simple, can't start and stop

I find the syntax of the latter confusing.

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
user379468
  • 3,989
  • 10
  • 50
  • 68

6 Answers6

240

I would recommend node-cron. It allows to run tasks using Cron patterns e.g.

'* * * * * *' - runs every second
'*/5 * * * * *' - runs every 5 seconds
'10,20,30 * * * * *' - run at 10th, 20th and 30th second of every minute
'0 * * * * *' - runs every minute
'0 0 * * * *' - runs every hour (at 0 minutes and 0 seconds)

But also more complex schedules e.g.

'00 30 11 * * 1-5' - Runs every weekday (Monday through Friday) at 11:30:00 AM. It does not run on Saturday or Sunday.

Sample code: running job every 10 minutes:

var cron = require('cron');
var cronJob = cron.job("0 */10 * * * *", function(){
    // perform operation e.g. GET request http.get() etc.
    console.info('cron job completed');
}); 
cronJob.start();

You can find more examples in node-cron wiki

More on cron configuration can be found on cron wiki

I've been using that library in many projects and it does the job. I hope that will help.

Tom
  • 26,212
  • 21
  • 100
  • 111
  • 1
    ok, I was intimidated by the cron syntax, but this seems like the best approach – user379468 Dec 10 '13 at 16:22
  • 1
    wait I spoke to soon, how would I write a cron that runs every 5 seconds or every 30 seconds? – user379468 Dec 10 '13 at 16:28
  • 3
    cron syntax might look _scary_. On the other hand it exist for long time and is widely know so will get lots of support on SO – Tom Dec 10 '13 at 16:28
  • 1
    Just updated my response so it would be - '*/5 * * * * *' - every 5 seconds or '*/30 * * * * *' seconds – Tom Dec 10 '13 at 16:30
  • What would a cron pattern to run say, every 50 minutes look like. I tested with 45 minutes with the following pattern '00 */45 * * * *' I run at 8:17 AM, and the job was triggered at the following times 8:45AM and the next was run at 9:00AM Doesn't make sense to me, please help – SamAko Jun 17 '14 at 09:00
  • @elimence, That script will won't work every 45 minutes as `*/45` for minutes is nothing more than `0,45` - that's why it executed at 8.45AM and then 9.00AM. I haven't run into that kind of issue before but it seems to be very interesting problem. There are some SO questions regarding similar problems and the solutions may help you out e.g. http://stackoverflow.com/a/14518023/1916110 – Tom Jun 25 '14 at 08:34
  • @Tom Took a look, and it's an interesting analysis. I'm wondering, assuming just two fields, namely, minutes and hours, what would the following pattern resolve to? `*/45 */2` I'm thinking the two hours would be divided into 45-minute blocks Is my thinking right? – SamAko Jun 26 '14 at 09:41
  • Thanks this helped a lot with preventing the heap size from growing. – Brian van Rooijen Jan 20 '16 at 11:32
  • Is this library a good choice if I need to clear a certain variable in all of my documents and bounce its value into another variable every 24 hours? Are there multiple time-zone accommodations? – MadPhysicist Sep 06 '16 at 20:35
  • @MadPhysicist, that library does support time zones. You can have a look at unit tests for some examples: https://github.com/ncb000gt/node-cron/blob/master/tests/test-cron.js. As far as your application requirements are concerned, it is very hard for me to make any judgment if this or other particular library is good or not, without knowing anything about your application. As far as scheduled jobs execution (main purpose of this library), it works very well. – Tom Sep 16 '16 at 09:41
  • @Tom thanks I shall give it a go. – MadPhysicist Sep 16 '16 at 17:14
  • cron.job is work in same thread or start new thread ? – Kaushik Makwana Mar 30 '18 at 08:58
  • @KaushikMakwana node.js are a single-thread programs and the same applies to node-cron. – Tom Mar 31 '18 at 08:12
  • 2
    As of year 2020, and as per [node-cron](https://www.npmjs.com/package/node-cron) official npm page, use of this package has gone down. This package was last published in npm 2 years ago, hence is not regularly updated. Now, rather another package [node-cron](https://www.npmjs.com/package/cron) which apparently has same name but goes by different URL should be preferred. – n0noob Jul 05 '20 at 14:35
  • [Bree is the best job scheduler for Node.js](https://jobscheduler.net) with support for cron, dates, ms, later, and human-friendly strings. [View our GitHub here](https://github.com/breejs/bree). `npm install bree` *NOTE:* I'm a former core maintainer of Agenda, and core team member of node-cron, Koa, and Express. I strongly recommend you to use Bree as it also takes advantage of Worker threaders which will sandbox your jobs from one another. I have used Agenda, Bull, node-cron, and other solutions in-depth and created Bree out of frustration with them. Thanks! –  Jul 18 '20 at 20:49
38

I've used node-cron and agenda.

node-cron is a very simple library, which provide very basic and easy to understand api like crontab. It doesn't need any config and just works.

var cronJob = require('cron').CronJob;
var myJob = new cronJob('00 30 11 * * 1-5', function(){...});
myJob.start();

agenda is very powerful and fit for much more complex services. Think about ifttt, you have to run millions of tasks. agenda would be the best choice.

Note: You need Mongodb to use Agenda

var Agenda = require("Agenda");
var agenda = new Agenda({db: { address: 'localhost:27017/agenda-example'}});
agenda.every('*/3 * * * *', 'delete old users');
agenda.start();
Ryan Wu
  • 5,963
  • 2
  • 36
  • 47
17

I think the best ranking is

1.node-schedule

2.later

3.crontab

and the sample of node-schedule is below:

var schedule = require("node-schedule");
var rule = new schedule.RecurrenceRule();
//rule.minute = 40;
rule.second = 10;
var jj = schedule.scheduleJob(rule, function(){
    console.log("execute jj");
});

Maybe you can find the answer from node modules.

Community
  • 1
  • 1
Richard Xue
  • 307
  • 2
  • 5
10

I have written a node module that provides a wrapper around setInterval using moment durations providing a declarative interface:

npm install every-moment

var every = require('every-moment');

var timer = every(5, 'seconds', function() {
    console.log(this.duration);
});

every(2, 'weeks', function() {
    console.log(this.duration);
    timer.stop();
    this.set(1, 'week');
    this.start();
});

https://www.npmjs.com/package/every-moment

https://github.com/raygerrard/every-moment

raygerrard
  • 812
  • 11
  • 13
  • 4
    The github link is broken (404) – kekko12 Aug 24 '17 at 13:07
  • this is much readable. i have written a package which uses `node-cron` as @Tom answer. and has a nice syntax similar to yours. `reel().call(() => console.log('hello !!')).everyMinute().run()` https://github.com/shakee93/node-reel – shakee93 Aug 05 '18 at 17:43
  • @kekko12 There is on the NPM: https://www.npmjs.com/package/every-moment – Ali Hesari Nov 15 '18 at 13:25
  • what to do for running the task after a month after month – Biku7 Jan 15 '21 at 07:13
  • To run something on a longer interval, like every month, you need to pick one of the packages that uses a database, like Agenda. Most of these keep the schedule in memory, which means a task schedule to run every month will run for the first time only after the process has been running for a month. Or if you use an absolute schedule (like "the first day of each month") and the process is restarted on that day then it will run more than once. – Jason Kohles Jan 14 '22 at 16:43
6

nodeJS default

https://nodejs.org/api/timers.html

setInterval(function() {
    // your function
}, 5000);
Rodrigo Adachi
  • 101
  • 1
  • 2
1

I have written a small module to do just that, called timexe:

  • Its simple,small reliable code and has no dependencies
  • Resolution is in milliseconds and has high precision over time
  • Cron like, but not compatible (reversed order and other Improvements)
  • I works in the browser too

Install:

npm install timexe

use:

var timexe = require('timexe');
//Every 30 sec
var res1=timexe(”* * * * * /30”, function() console.log(“Its time again”)});

//Every minute
var res2=timexe(”* * * * *”,function() console.log(“a minute has passed”)});

//Every 7 days
var res3=timexe(”* y/7”,function() console.log(“its the 7th day”)});

//Every Wednesdays 
var res3=timexe(”* * w3”,function() console.log(“its Wednesdays”)});

// Stop "every 30 sec. timer"
timexe.remove(res1.id);

you can achieve start/stop functionality by removing/re-adding the entry directly in the timexe job array. But its not an express function.

Simon Rigét
  • 2,757
  • 5
  • 30
  • 33