Running Laravel Queues with systemd Instead of Supervisor

Many Laravel deployments still use Supervisor to keep queue workers running. On systemd-based distros, you can let the init system do the job instead.

Why use systemd for Laravel workers?

  • Already installed and managed by the OS
  • Native logging with journalctl
  • Restart policies and resource limits per service

You end up with fewer moving parts and simpler automation via systemctl.

Basic systemd unit for a queue worker

Create /etc/systemd/system/laravel-queue-worker.service

INI
[Unit]
Description=Laravel Queue Worker
After=network.target

[Service]
User=www-data
Group=www-data
Restart=always
RestartSec=5
StartLimitIntervalSec=0

Environment=APP_ENV=production
Environment=APP_DEBUG=false
WorkingDirectory=/var/www/myapp/current

ExecStart=/usr/bin/php artisan queue:work --sleep=3 --tries=3 --max-time=3600

StandardOutput=append:/var/log/laravel-queue.log
StandardError=append:/var/log/laravel-queue-error.log

[Install]
WantedBy=multi-user.target

Reload and restart:

Bash
sudo systemctl daemon-reload
sudo systemctl enable --now laravel-queue-worker.service

Check status and logs:

Bash
sudo systemctl status laravel-queue-worker.service
sudo journalctl -u laravel-queue-worker.service -f

Handle deploys safely

During deploys you usually:

  • Upate code
  • Run migrations
  • Restart workers

Create a simple service override to ensure workers restart correctly:

Bash
sudo systemctl edit laravel-queue-worker.service

Then:

Bash
[Service]
ExecStop=/usr/bin/php artisan queue:restart
TimeoutStopSec=60

Now systemctl restart triggers Laravel’s own graceful restart mechanism.

Example deploy hook:

Bash
ssh deploy@server << 'EOF'
  cd /var/www/myapp/current

  php artisan migrate --force

  sudo systemctl restart laravel-queue-worker.service
EOF

Multiple queues and priorities

You can run multiple units for different queues. For a high-priority emails queue:

/etc/systemd/system/laravel-queue-emails.service:

INI
[Unit]
Description=Laravel Queue Worker (emails)
After=network.target

[Service]
User=www-data
Group=www-data
Restart=always
RestartSec=3

WorkingDirectory=/var/www/myapp/current
ExecStart=/usr/bin/php artisan queue:work --queue=emails --sleep=1 --tries=5

StandardOutput=append:/var/log/laravel-queue-emails.log
StandardError=append:/var/log/laravel-queue-emails-error.log

[Install]
WantedBy=multi-user.target

Enable it:

Bash
sudo systemctl enable --now laravel-queue-emails.service

Common mistakes and fixes

MistakeFix
Using php artisan queue:listen in systemdUse queue:workqueue:listen is mainly for development and more resource heavy.
Forgetting to set WorkingDirectoryAlways set it to your app root so artisan finds .env and vendor.
Running as rootUse the web user (often www-data) and ensure permissions on storage / bootstrap/cache are correct.

Once configured, you get robust workers with first‑class OS integration and one less dependency to manage.


Posted

in

, , ,

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *