Adding a cron scheduler in Laravel Forge

Posted on December 23, 2025

Laravel Forge

Since the latest Forge re-launch earlier this year, you need to be a little more "hands on" when setting up your cron jobs.

It's easy once you know, but this will save you time on figuring out why my commands aren't firing.

No downtime deployments

This is an option you will see as a checkbox when setting up your new Forge server. If you have enabled no downtime deployments, your folder structure is slightly different to historical Forge hosted websites.

Regular structure:

/home/forge/website.com

No downtime structure:

/home/forge/website.com/current

As you can see, the additional directory current is added beneath your website's root, which hosts all of your regular Laravel files and directories.

Run cd website.com && ls and notice there is also a folder releases. This will host the previous deployments in this directory, named as a timestamp of that particular deployment. Forge automatically cleans these up (based on your retention settings).

Scheduler

Anyway, back to the scheduler.

  1. In Forge navigate to your server and then website.com.
  2. Go to processes and then scheduler.
  3. Click 'Add Scheduled Job'. You will now see options to add a name, command, user and the frequency.

Name

Call this scheduler whatever you'd like.

Command

This is the confusing bit you have to get right. The placeholder looks something like this:

php /home/forge/website.com/current/artisan

But this isn't quite what you want. On the latest version of Forge I have noticed the php prefix by default does not work. You must ensure this is the actual php version e.g. I'm using 8.4 so the prefix becomes php8.4 (no space).

php8.4 /home/forge/website.com/current/artisan

You will then need to finish this command with schedule:run.

php8.4 /home/forge/website.com/current/artisan schedule:run

User

Unless you have a custom setup, you can leave this as 'forge'.

Frequency

It's likely you want this cron to run all the time, so you can select 'Every minute' here.

Finishing up

Once that is all done click the three dots next to your created scheduled and click "Show Output".

You should now see the output as INFO No scheduled commands are ready to run..

If you want to test this, deploy a new run with the default Artisan Inspring quote running every minute and view the output in your log file.

Artisan::command('inspire', function () {
    logger(Inspiring::quote());
})->describe('Display an inspiring quote')
    ->everyMinute();
Back to Posts