node cron jobs on heroku, is using the heroku scheduler necessary? - node.js

I'm building my app backend as a node/express API to be deployed on Heroku.
I am new to implementing "cron jobs", and I found the npm library named node-cron which seems very straightforward.
Is it as simple as just setting up the cron job in my app runtime code? I know it will not run when the heroku free dyno goes into "sleep mode" (based on other StackOverflow answers), but I plan to use paid dynos in production so that's not an issue.
My main concern is when I "scale up" on heroku and run multiple dynos, will this cause weird interactions? Will every "instance" of my app on a separate dyno try to run its own crons independantly, causing duplication of work?
I know heroku provides a free "scheduler" addon for this to spin up dynos to do this, but if the above won't happen, the scheduler heroku addon seems to be unneeded overhead in my case.
Notes: my cron will be very simple, just doing some database clean up on old records, I didn't want to do it in the database layer to keep things simpler as it seems not super easy to schedule jobs in postgres.
Any insights will be much appreciated. Thank you.

As you mentioned above all things are correct as per my past experience with the same situation.
npm package node-cron only works fine if you have only one dyno
otherwise it will trigger based on a number of dynos.
If you want to execute the cron perfectly without taking any risk (doesn't matter how much dyno's you have) I suggest you to use heroku add-on.

Related

How to schedule node.js code to run at a specific time daily outside times given in scheduler?

So, I see that heroku provides the option to run a command at a specific time. Information on the scheduler here.
LINK: https://elements.heroku.com/addons/scheduler
However, if you go through the steps when setting it up, they do not provide a lot of flexibility on when you can run your code daily. For example, you can only run code at 4:00pm or 4:30pm, not 4:10pm.
How can I make it so that a node.js file would run on heroku at a specific time (like 4:10pm or 2:15pm, some time outside the options given on heroku) on a daily basis?
There appears to be no support for node.js explaining this either on their website.
Might be just a work around, but you could start the process at the nearest time slot, that is before your desired time, let it run and wait passively until your desired time and let it do the actual task just then.
However notice as Heroku mentions in the documentation Heroku Scheduler isn't guaranteed to run the task, even though it's very reliable. If you need something critical or have something that has to been run everyday for sure, you should probably make a separate process, which handles the scheduling.
We've added a simple Heroku add-on called Cron To Go that does exactly that - you can use Cron expressions for accuracy and schedule one-off Dynos, just like with Heroku Scheduler.
There's also a simple Node example here.

Heroku Hobby server still sleeps or issue with NodeJS?

I've noticed that my NodeJS application which resides on a Heroku Hobby server after no activity does a "soft restart". By that I mean it doesn't do big actions like reinitialize the ORM system or recreates the HTTP server, however it does seem to forget callback functions and global variables or any variables that were dynamically created and held in memory.
Does Heroku still "sleep" even with the Hobby plan or is it something related to NodeJS?
As indicated by Heroku's documentation, Hobby dynos do not sleep.
However, dynos of all types are restarted frequently:
Automatic dyno restarts
The dyno manager restarts all your app’s dynos whenever you:
create a new release by deploying new code
change your config vars
change your add-ons
run heroku restart
Dynos are also restarted (cycled) at least once per day to help maintain the health of applications running on Heroku. Any changes to the local filesystem will be deleted.
I'm not entirely clear what you mean by
it does seem to forget callback functions and global variables or any variables that were dynamically created and held in memory
but at least some of these things could happen due to automatic dyno restarts. Certainly anything that only exists in memory will be lost.
You could manually restart your dynos using heroku ps:restart and see if that replicates the behaviour you are seeing. You may need to adjust your code to survive being restarted.

How to warm up a Heroku Node.js server?

Heroku reboots servers everyday. After reboot, my node server takes around 20 seconds to load a page for the first time. Is there a way to prevent this?
EDIT: You guys seem to be misunderstanding the situation. In Heroku, even production servers must be restarted daily. This is not the same as a free server sleeping. This question is aimed more at preventing lazy-loading and pre-establishing connection pools to databases.
Old question, but in case others stumble upon it like I did
Use can use Heroku's Preboot feature:
Preboot changes the standard dyno start behavior for web dynos. Instead of stopping the existing set of web dynos before starting the new ones, preboot ensures that the new web dynos are started (and receive traffic) before the existing ones are terminated. This can contribute to zero downtime deployments
You could also combine it with a warmup script like the one described in this Heroku post

How to schedule Heroku's (maintenance mode or recharge) at specific time of the day?

I'm trying to keep my Heroku (free) application awake during daytime. I don't really care if it sleeps late at night.
The old technique of continuously pinging the app is no longer a valid solution because since 2015, all free-app's have to sleep at least 6 hours a day.
I'd like to know if any of you guys figured this out before.
I need to schedule the recharge state or maintenance mode in a specific time range.
Let's make this question and an up-to-date resource of accomplishing this task.
Please submit only constructive ideas.
You can just scale it down for the six hours you want it to be asleep:
heroku scale web=0
Then scale it back up when you want to wake it up:
heroku scale web=1
There are a lot of ways to implement this; a script on some other machine would work fine, but you could probably also use the Heroku Platform API and a scheduler service:
https://devcenter.heroku.com/articles/platform-api-reference#formation
https://devcenter.heroku.com/articles/scheduler
disclosure: I'm the Node.js Platform Owner at Heroku
There is also this add-on: https://devcenter.heroku.com/articles/process-scheduler
At first I thought it wasn't working as it doesn't seem to necessarily run right at the top of the hour, but other than that it's been working really well for me and allows me to sleep my app overnight.

Running Cron Tasks on Heroku

I've seen that Heroku charges $15/mo to run Delayed Job, and $3/mo to run cron tasks daily. Is it possible to skip that entirely and run my own cron tasks manually? Or are they somehow figuring out that I'm running cron tasks?
I'm not entirely sure what you mean by "run my own cron tasks manually". For cron specifically, you need access to crontab, which they can control, as they're their servers. If you have another way of doing it, it would probably be fine, but bear in mind that your app is not tied to a specific server when running under Heroku, and that the server will change between executions.
Also, unless they've changed it since last time I checked, you can run daily cron tasks for free, but hourly costs $3/mo.
EDIT: Yes, daily crons are free. See http://addons.heroku.com/.
If you install the Heroku gem on your computer, you can then run your cron tasks manually as follows:
$ heroku rake cron
(in /disk1/home/slugs/xxxxxx_aa515b2_6c4f/mnt)
Running cron at 2010/04/25 10:28:54...
This will execute the exact same code as Heroku's daily/hourly cron add-on does; that is, for this to work, your application must have a Rakefile with a cron task, for example:
desc "Runs cron maintenance tasks."
task :cron do
puts "Running cron at #{Time.now.strftime('%Y/%m/%d %H:%M:%S')}..."
# TODO: your cron code goes here
end
Now, just add the heroku rake cron command to a crontab on any Unix server of yours, or even directly to your personal computer's crontab if you're running Linux or Mac OS X, and you can be scheduling cron jobs for your Heroku application as you please and without being charged for it.
Updating the answer for 2020:
You can use Heroku Scheduler which is Heroku's own add-on that lets you schedule commands using one-off dynos (so that you only pay for the run time of your jobs). The add-on itself is free, but doesn't really allow you to use cron but rather plain frequency: every day, every hour or every 10 minutes. Also, there's no guarantee that your job will execute at the scheduled time or at all..
There are other 3rd party add-ons that can help you run one-off dynos using cron expressions for better flexibility and are more resilient than Heroku Scheduler (proper disclosure, my company is the creator of one such add-on).
You can also use custom clock process (see here for more info) which essentially means that you have one dyno or process spawn tasks that run on other dynos. This usually costs more than using the aforementioned add-ons, but you have more granular control over your processes and since you only rely on Heroku, it may be more stable.
Yes, I've successfully used a cron job on my local server which essentially runs
$ heroku rake <rake task>
at whatever intervals I've required. I've used in on both aspen and bamboo stacks.
You can also just install a gem like rufus-scheduler if you're running a rails app and setup scheduling that way. I don't know if this is bad practice for some reason, but it's what I do with my app, and it seems to work fine.
If you want to have scheduled jobs you can also use http://guardiano.getpeople.in that is a free service (for 10 jobs) for job scheduling.
You just need to setup an HTTP endpoint in your application to recieve event notifications on POST or GET and you can also set some additional params to prevent not authorized actions.
So you set a job in Guardiano that will cal http://yourapp.com/youraction and leave "minutes" blank if you want you action to run once in the future or set minutes to what you want to run your action every X minutes. In that way you only have to create your endpoint for you app and when this EP is called you execute something.
So your app can sleep and you don't need to spend money and time setting up jobs and taking care that they are working properly.
IMHO if you need something fast for an MVP or you need to setup a lot of jobs for different apps than a free service like that where you can actually outsource cronjobs is quite good.
There was aslo an Heroku Addon called Temporize to do that but I'm not sure is still alive and working

Resources