This add-on is operated by MISC CO BV
Reliable and powerful task scheduling as a service.
Last updated 17 October 2020
Table of Contents
Advanced Scheduler is an add-on that provides task scheduling as a service.
The service is built on the same principles as Heroku Scheduler, and it distinguishes itself by providing greater flexibility, transparency, and reliability in a cost-effective way.
All features are accessible from the Advanced Scheduler dashboard. It allows you to configure triggers that execute your tasks once on a specific date and time, or at a certain time interval. When executed, these tasks run in one-off dynos and show up in your application’s logs. This service is language-agnostic, meaning it can be integrated regardless of the programming language you use.
Advanced Scheduler depends on the Heroku Platform API for task execution. If the API is unavailable, execution of your scheduled tasks can be missed. If scheduled tasks are a critical component of your application, it is recommended to run a custom clock process instead.
Provisioning the add-on
Advanced Scheduler can be attached to a Heroku application via the CLI:
A list of all plans available can be found here.
$ heroku addons:create advanced-scheduler -----> Adding advanced-scheduler to sharp-mountain-4005... done, v18 (free)
After you install Advanced Scheduler, your application should be configured to fully integrate with the add-on. If you are new to task scheduling, you can read up on defining, testing, scheduling and debugging tasks below.
Tasks are any command that can be run in your application.
Almost every framework or language has a convention to define such a command. Some have a built-in feature for setting up tasks, while others require you to add a script to
bin/ that will perform the task.
Note that each framework or language might define tasks in a different way. Refer to the best practices for the framework or language you are using inside your application.
For Rails, the convention is to set up rake tasks. To create your task in Rails, copy the code below into
lib/tasks/scheduler.rake and customize it to fit your needs.
desc "This task is called by the Advanced Scheduler scheduler add-on" task :update_feed => :environment do puts "Updating feed..." NewsFeed.update puts "done." end task :send_reminders => :environment do User.send_reminders end
#!/usr/bin/env ruby require "sequel" DB = Sequel.connect ENV["DATABASE_URL"] puts "Cleaning old sessions..." DB["DELETE FROM sessions WHERE last_seen_at < ?", Time.now - 24*60*60] puts "done."
Note that if you are using a script, an interpreter might be needed in the command above to execute your task correctly. To prevent this, add a shebang at the top of your script (e.g.,
#!/usr/bin/env node for Node.js or
#!/usr/bin/env ruby for Ruby). This tells the system which interpreter to use to execute the script.
Once you have written your task and see that it is functioning locally, the next step is to deploy your application and test your task on Heroku.
To do so, use
heroku run to run your task on Heroku:
$ heroku run <your-task>
To schedule a task, you need to create a new active trigger for it. Triggers are configured using the Advanced Scheduler dashboard.
Enter the task and specify if the trigger needs to be executed only once or at a certain time interval. For one-off triggers, define a date and time at which the task should be executed. For recurring triggers, provide a standard cron expression or use the schedule helper to define the interval. As a tip, check your cron expressions here to verify they are correct. By default, a new trigger will be activated directly after creation. If you do not want this behaviour, you can configure the trigger to stay inactive.
Instead of specifying a command, you can specify one of the process types in your app’s Procfile. The command associated with the process type will then be executed, together with any parameters you supply. See the syntax for one-off dynos to learn more.
Note that for each plan there are limits on the total number of tasks that can be scheduled at one point in time, as well as the total number of task executions in one month. Once one of these limits is exceeded, attempts to schedule a new task will fail.
To debug a task, you have to check your application’s logs. You can check your logs in real time or use any of the logging add-ons available in the Heroku Marketplace.
To check your real-time logs, use the
heroku logs command:
$ heroku logs -t -a <your-app> -d advanced-scheduler 2020-01-15T14:10:16+00:00 heroku[advanced-scheduler.1]: State changed from created to starting 2020-01-15T14:10:16+00:00 app[advanced-scheduler.1]: Starting process with command `node bin/send-newsletter.js` 2020-01-15T14:10:19+00:00 app[advanced-scheduler.1]: Sending newsletters... 2020-01-15T14:10:27+00:00 app[advanced-scheduler.1]: done. 2020-01-15T14:10:28+00:00 heroku[advanced-scheduler.1]: State changed from up to complete
A running task is also visible with the
heroku ps command:
$ heroku ps === advanced-scheduler (Free): node bin/send-newsletter.js (1) advanced-scheduler.1: up 2020/01/15 14:10:16 +0100 (~ 2s ago)
The task monitoring of Advanced Scheduler depends on the result of your task. Make sure your task exits with the right exit code (sometimes referred to as a return status or exit status). A successful task returns a 0, while an unsuccessful one returns a non-zero value.
Although it is generally recommended to keep tasks lightweight and quick to execute, Advanced Scheduler can be used for longer-running tasks. Make sure to only have 1 task running by setting the execution interval higher than the task’s maximum execution time. In the event that a specific task does run longer than intended, you can force the task to exit by setting its trigger’s timeout value to the maximum allowed execution time. See tasks timing out to learn more.
Note that a task can run for up to 24 hours by settings its trigger’s timeout value to 86400 seconds.
Concurrent one-off dyno limits
The limit for your app’s concurrently running one-off dynos depends on several factors. See which limit applies to your situation.
Beware that when exceeding your app’s concurrent one-off dyno limit, the next task might not be executed.
To stay below Heroku’s concurrent one-off dyno limit, make sure to plan the execution of your tasks with care. Avoid a backlog of one-off dynos created when scheduled tasks are executed before running tasks are finished or time out.
Alternatively, you can contact Heroku to get your limit raised.
The Advanced Scheduler dashboard allows you to configure one-off and recurring triggers that execute different tasks.
You can access the dashboard via the CLI:
$ heroku addons:open advanced-scheduler Opening advanced-scheduler for sharp-mountain-4005
or by visiting the Heroku Dashboard and selecting the application in question. Select Advanced Scheduler from the Add-ons menu.
By default, Advanced Scheduler monitors the executions of your scheduled tasks. For every trigger an email notification is sent on the first failed execution each day.
Note that the successful or failed execution of your task depends on the process exit code (sometimes referred to as a return status or exit status), so make sure your process is exiting properly. When the process exits with code 0, the execution is considered successful. Anything else is treated as a failed execution.
Tasks timing out
When a task runs longer than its trigger’s timeout value, it will be forced to exit shortly after. This mechanism is intended to either prevent a backlog of one-off dynos or to ensure only 1 task of a specific trigger is running at a time. Always aim to make tasks finish by themselves. When a task does time out, make sure to figure out why and take action to prevent it from happening again.
Note that the default timeout value for new triggers is 1800 seconds or 30 minutes and the maximum timeout value is 86400 seconds or 24 hours.
Migrating between plans
Note that application owners should carefully manage the migration timing to ensure proper application function during the migration process.
heroku addons:upgrade command to migrate to a new plan.
$ heroku addons:upgrade advanced-scheduler:newplan -----> Upgrading advanced-scheduler:newplan to sharp-mountain-4005... done, v18 ($49/mo) Your plan has been updated to: advanced-scheduler:newplan
Removing the add-on
You can remove Advanced Scheduler via the CLI:
This will destroy all associated data and cannot be undone!
$ heroku addons:destroy advanced-scheduler -----> Removing advanced-scheduler from sharp-mountain-4005... done, v20 (free)
All Advanced Scheduler support and runtime issues should be submitted via one of the Heroku Support channels. Any non-support related issues or product feedback is welcome at firstname.lastname@example.org.