Vapor: Sub-Minute Scheduled Tasks

Dec, 21 2023#vapor

To invoke Laravel's internal scheduler, you must call the schedule:run Artisan command once every minute. In a traditional serverful hosting environment, you may achieve this using a utility such as cron.


However, in a serverless Vapor environment, there is no "always-on" server to run cron. Instead, our Lambda functions react to process the workload as and when we need them to. To work around this, Vapor invokes the scheduler using AWS EventBridge, which allows us to write cron-like expressions and define what to do when that expression passes - in our case, invoke the CLI function and call the schedule:run command.

Using EventBridge is an elegant solution to invoking the scheduler in a serverless environment. However, there is one caveat. The AWS documentation states the following:

The finest resolution for an EventBridge rule that uses a cron expression is one minute. Your scheduled rule runs within that minute but not on the precise 0th second.

Until recently, this wasn't an issue. We only needed the scheduler to be called once per minute - it didn't matter how many seconds past the minute.

With the release of Laravel 10.15, sub-minute scheduling was added to the framework. When using this functionality, invoking the scheduler at the beginning of every minute is imperative for it to work as expected.

For example, when scheduling a command using Laravel's everyThirtySeconds method and assuming EventBridge invokes the scheduler at 12:00:10, the commands would actually run at 12:00:10 and 12:00:40.

When using everySecond, the seconds at the beginning of the minute would be missed entirely.

Although this is not an issue for everyone, we wanted to provide Vapor users with the option to enable the expected behavior of sub-minute scheduling.

Beginning today, you may enable sub-minute scheduling support by simply updating your application's vapor.yml configuration file:

id: 2
name: vapor-laravel-app
        scheduler: sub-minute
        cli-timeout: 120

After setting scheduler: sub-minute and deploying your application, Vapor will update EventBridge to call vapor:schedule instead of schedule:run. The vapor:schedule command waits for the beginning of the next minute before calling schedule:run, thus ensuring Laravel's scheduler starts when expected.

You may have noticed the cli-timeout was explicitly set to 120 in the vapor.yml example above. The CLI needs to run for at least two minutes to ensure there is enough time to wait until the beginning of the next minute and allow every second of the sub-minute scheduler to execute. You may need to set this timeout to a larger value if any of your commands take significant time to complete. You should also ensure your cli-concurrency is at least 2 and you are running Vapor Core >= v2.34.0.

We hope you like this exciting new update, which is available today. At Vapor, we strive to build the best experience for hosting your Laravel applications in a serverless environment. We'd love to hear any feedback you may have.

By Joe Dixon

Software Developer at Laravel.

Find me on Twitter, GitHub or my blog.

Follow the RSS Feed.