Adding a cron scheduler in Laravel Forge
Posted on December 23, 2025
Laravel ForgeSince 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.
- In Forge navigate to your server and then website.com.
- Go to processes and then scheduler.
- 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();