Tangible Bytes

A Web Developer’s Blog

Laravel Scheduled Tasks on Kubernetes

I have some tasks I want to schedule on a Laravel System that runs on Kubernetes

I have concluded that for my use case the Laravel Scheduler is not suitable and I’m instead defining console commands and running them via Kubernetes Cron as needed.

The way Laravel Scheduler works

(for tasks schedule at over 1 minute intervals) is just by comparing the task frequency with the current time

If you run a task

  • every minute - will run every time schedule:run does
  • every two minutes - when run if the minute is even
  • every 5 minutes - when run if the minute ends 5 or 0
  • etc

Laravel is not tracking if the task has run

If a task is set to run every hour and the task that runs it does not run between 0 minutes and 5 minutes past the hour - it will not run for another hour

If the task is run twice in the allotted minute - it will be run twice.

See : https://stackoverflow.com/a/48688221/1537692

Kubernetes

In Kubernetes a cron job involves spinning up a container, initialising it, and then running the task.

This is quite heavyweight and seems overkill to do every minute when I know that I only have tasks that need to run hourly

I could run a deployment and run artisan schedule:work which then runs more like a daemon and saves all the start/stop activity.

But it still uses up memory the whole time it is running.

Whereas if I run a cron and kubernetes is short of memory - it will delay the cron - which in my case is far preferable to crashing the webserver.

Code Clarity

I think it’s clearer to have Cron helm manifests in my repo than to have tasks in my route files

Either way the cronjobs are set in code in the same repo

I think seeing the status of any failed cronjobs in the Kubernetes logs will be clearer with those jobs directly responsible for specific tasks than if they are just running the scheduler.