Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Shengjie's avatar

What is the best practice to run schedule on production server

It's my first time using Task Schedule to backup the database. Should I just execute nohup php artisan schedule:work on my production server or is there any better way to start the schedule. Thanks

0 likes
9 replies
Tippin's avatar
Tippin
Best Answer
Level 13

On a normal server, you simply create the cron job that will execute the schedule:run command once per minute. You should never use schedule:work outside of developing locally.

https://laravel.com/docs/8.x/scheduling#running-the-scheduler

Essentially just making the single cron job:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

* * * * * in cron terms means once per minute.

The only time in my experience where I do not use this cron job to trigger it, is in a kubernetes stack I watch over, since part of the deployment spins up a container "job" once per minute to run it instead.

1 like
Shengjie's avatar

Hi @Tippin Could you please explain how to match up the schedule in Cron job and Laravel? For example, What would happen if the Cron job executes schedule:run every Monday and in Laravel, the backup command is scheduled to run every Tuesday?

Tippin's avatar

@Shengjie I think you are mistaken how the scheduler and cron works. Essentially the cron job runs the schedule:run command every single minute of every day. When it runs, laravel then boots up and determines if the current time matches any of your defined scheduled task in your console kernel.

https://laravel.com/docs/8.x/scheduling#schedule-frequency-options

So if you define a command to run everyFiveMinutes then any time matching a 5 minute mark upon the cron running the schedule command will execute. So 00, 05, 10, 15, 20, etc minutes of each hour would match.

For your example, you would define your scheduled backup command to run ->weeklyOn(2, '1:00') meaning so long as the cron runs the scheduler anytime within the 1am mark on Tuesdays, it will execute your backup.

Basically you get to define the intervals cleanly and fluently for any scheduled task you may have in your app in one spot, having one cron run the scheduler every minute...vs you making cron jobs manually for every single thing you want automated.

1 like
DaveBiddle's avatar

@tippin Thanks for your excellent explanation of the scheduling flow, I was wondering though if there is a good reason why you say: "You should never use schedule:work outside of developing locally."

I'm running Laravel in a production container hosting scenario, where there isn't an opportunity to run a cron job to invoke the scheduler once every minute.

As a workaround I added a worker container running artisan schedule:work , and this has the desired effect.

So I'm wondering if there's something I should be aware of about artisan sechedule work which makes it unsuitable for production use?

Tippin's avatar

@DaveBiddle I was mainly parroting what the documentation says, which is that schedule:work was intended for development only, and not production. On that note, we use kubernetes and have it as one of our deployments using a kubernetes cronJob service (where the cronJob uses our base php as the image and simply calls the schedule run command directly when the container comes up each minute). Possibly check out:

https://www.howtogeek.com/devops/how-to-use-cron-with-your-docker-containers/

DaveBiddle's avatar

@Tippin Thanks I checked out that link, think I'll go with the 'separate container with cron as the foreground process' route. Thanks for the help. :)

1 like
DaveBiddle's avatar

In case this helps anyone who might be stuck trying to get the cron daemon running in their container to use the environment variables that their user sees inside the container, I eventually abandoned cron in favour of a while loop in a Bash script which is run on CMD in the Dockerfile. Details here: https://laravel-news.com/laravel-scheduler-queue-docker

jackkitley's avatar

@DaveBiddle Ive been using this but lately found that some commands are being skipped....

while [ true ]
do
  php artisan schedule:run --verbose --no-interaction
  sleep 60
done

Use this as is but never put & at the end as it ramped up the CPU

Snapey's avatar

@jackkitley If you sleep 60 and a job takes a few seconds then you can skip minutes entirely.

EG, you come out of sleep at 07:59:58

You run a job that takes 4 seconds to run

You finish the job and sleep until 08:01:02

Now you have missed running any jobs that were supposed to run at 08:00.

Don't consider just reducing the sleep, because then you have the risk of running a job twice.

Best solution is to use Cron. Don't know why this is not possible in your case.

Please or to participate in this conversation.