Articles on: 🌍 Web Hosting & PaaS
This article is also available in:

How do I run background workers (queues, Horizon, Messenger)?

Laravel queues, Laravel Horizon and Symfony Messenger need a process that keeps running in the background to consume jobs. cPanel > Workers runs those for you, restarts them if they stop, and keeps them alive across reboots.


Until now the only option on shared hosting was a cron job that started and stopped a worker every minute. A supervised worker is always there, so a job is picked up the moment it is queued.


What you can run


  • Laravel queues - php artisan queue:work, the default for Mail::queue(), notifications, image processing and anything else you dispatch to a job.
  • Laravel Horizon - php artisan horizon, for apps that use Horizon to manage their queues. It needs Redis, which you can enable in cPanel > Redis.
  • Symfony Messenger - php artisan messenger:consume, one consumer for your configured transports.


💡 Good to know: your worker runs inside your own hosting space, with your own PHP version.


If you deploy with Hodifly: nothing to do


Hodifly sets the worker up on its own, on every deploy. It only does so when your application really needs one:


  • A Laravel app whose QUEUE_CONNECTION is a real driver (database, redis, ...) gets a queue:work worker.
  • An app that requires laravel/horizon gets a horizon process instead - never both, because Horizon manages its own pool and running the two together would process every job twice.
  • A Symfony app gets a messenger:consume worker for each transport that is not sync.
  • An app on QUEUE_CONNECTION=sync gets no worker, because it runs its jobs during the request. That is not a failure - a worker would sit idle.


After each deploy the worker is restarted automatically, so it always runs your new code and never the previous release.


Setting one up by hand


If you installed your application yourself rather than through Hodifly:


  1. Open cPanel > Workers and click Add a worker.
  2. Give it a short name (queue, emails, ...).
  3. Pick the type: Laravel queue:work, Laravel Horizon or Symfony Messenger.
  4. Choose the application folder. The field suggests the folders where we find a Laravel artisan or a Symfony bin/console, so you normally just pick yours from the list.
  5. Leave the queue names empty for the default queue, or list them separated by commas.
  6. Save. The worker starts straight away.


You can start, stop and restart each worker from the same page, and open its log to see the jobs it has processed.


How many workers can I run?


One worker process per vCore included in your plan. A plan with 4 vCores can run 4 workers, and a worker configured with several processes uses that many of them. The page shows your current usage, for example 2 / 4.


Background workers are included from the SITE PRO plan upwards. If you need more workers, moving to a plan with more vCores is what raises the limit.


Good practice


  • Stopping is graceful. When a worker is stopped or restarted it finishes the job it is currently handling first, so nothing is cut off halfway through. That can take a few seconds, which is normal.
  • Workers recycle themselves. Each one restarts periodically, which releases the memory long-running PHP tends to accumulate. The queue is never left unattended: the replacement starts immediately.
  • A worker that keeps crashing is stopped. If your application fails to start, we stop after a few attempts and show the state FATAL with the log, rather than retrying forever and consuming your resources. The cause is almost always in the application - read the log.
  • queue:work does not reload your code by itself. That is why Hodifly restarts it on every deploy. If you change a job class by hand (over SSH or FTP), restart the worker from the page.


Scheduled tasks are separate


Laravel's scheduler (schedule:run) is not a worker: it is a cron job, and Hodifly adds it on its own when your application schedules something. The two work together - the scheduler can queue jobs that your worker then processes.


What is not supported


WebSockets servers (Reverb, Soketi) and Laravel Octane are not available on shared hosting. For real-time features, use polling, or a virtual or dedicated server where you control the whole stack.

Updated on: 20/09/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!