> ## Content Index
> Fetch the complete content index at: https://www.blog.nestict.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Stop cPanel “Hung Service Checks”: Fix Runaway Laravel Queue Workers Caused by Cron
- URL: https://www.blog.nestict.com/stop-cpanel-hung-service-checks-fix-runaway-laravel-queue-workers-caused-by-cron/
- Published: 2025-08-28T10:55:03.000Z
- Updated: 2025-08-28T10:59:56.000Z
- Author: Nestict Infotech CSR
- Tags: Technology, Featured

**Slug:** stop-cpanel-hung-service-checks-laravel-queue-workers  
**Meta Description:** Seeing “Hung Service Checks” on cPanel/WHM with sky-high load averages? The culprit is often cron spawning unlimited Laravel `queue:work` processes. Here’s the exact fix with systemd or Supervisor, plus troubleshooting tips.  
**Reading Time:** 7–9 minutes  
**Categories:** DevOps, cPanel, Laravel, Performance  
**Tags:** cPanel, WHM, chkservd, CloudLinux, PHP-FPM, Laravel, queues, cron, systemd, Supervisor

---

## TL;DR

If your server is firing **“Hung Service Checks”** and showing **massive load averages**, you probably have a cron job starting a new `php artisan queue:work` **every minute**. That spawns hundreds of PHP processes and melts the CPU.

**Fix:**

- Run queue workers under **systemd** (or **Supervisor**) so there’s a **fixed number** of long-running workers.
- Add safety flags: `--sleep=3 --tries=3 --max-jobs=100 --max-time=3600`.

Keep **only** the scheduler cron:

```bash
* * * * * php /home/USERNAME/APP/artisan schedule:run >> /dev/null 2>&1

```

---

## Symptoms You’ll Notice

- cPanel/WHM notifications: **Hung Service Checks**.
- Load averages like `233.78 403.89 355.68`.
- `top` or `ps` shows many PHP/CGI processes:  
`artisan queue:work` and `artisan schedule:run`.
- Disk and memory look fine; CPU is pegged.
- Services “seem up,” but the server feels frozen or timeouts occur.

---

## Why This Happens

Laravel queues are designed to run as **long-lived workers**. If you start `queue:work` **via cron every minute**, each minute creates another worker without stopping the previous one. After hours, you have **hundreds** of workers competing for CPU—chkservd interprets the system as **hung**.

---

## The Correct Architecture

1. **Queue workers** should be managed by **systemd** (or **Supervisor**) as a **fixed** number of persistent processes.

**Cron** should run **only the scheduler**:

```bash
* * * * * php /home/USERNAME/APP/artisan schedule:run >> /dev/null 2>&1

```

---

## Step-by-Step Fix (systemd)

> Works great on CentOS/Alma/Rocky/CloudLinux with cPanel. Replace paths and PHP binary as needed.

### 1) Kill the Runaway Processes (Immediate Relief)

```bash
pkill -f "artisan queue:work"
pkill -f "artisan schedule:run"
systemctl restart httpd
systemctl restart php-fpm
systemctl restart mysql

```

### 2) Clean Up Your Crontab

- Remove any lines that start `queue:work`.

Keep only the scheduler:

```bash
* * * * * php /home/USERNAME/APP/artisan schedule:run >> /dev/null 2>&1

```

### 3) Create a systemd Service for Workers

Create `/etc/systemd/system/laravel-worker.service`:

```ini
[Unit]
Description=Laravel Queue Worker for myapp.example.com
After=network.target

[Service]
User=USERNAME
Group=USERNAME
WorkingDirectory=/home/USERNAME/APP
ExecStart=/opt/cpanel/ea-php84/root/usr/bin/php /home/USERNAME/APP/artisan queue:work --sleep=3 --tries=3 --max-jobs=100 --max-time=3600
Restart=always
RestartSec=5
StandardOutput=null
StandardError=null

[Install]
WantedBy=multi-user.target

```

Then enable it:

```bash
systemctl daemon-reload
systemctl enable laravel-worker
systemctl start laravel-worker
systemctl status laravel-worker

```

### 4) (Optional) Separate Queues by Priority

Create additional services, e.g. `/etc/systemd/system/laravel-worker-mail.service`:

```ini
ExecStart=/opt/cpanel/ea-php84/root/usr/bin/php /home/USERNAME/APP/artisan queue:work --queue=mail --sleep=3 --tries=3 --max-jobs=100 --max-time=3600

```

Start and enable them as above. This isolates critical queues (email, sms) from heavy jobs (thumbnails, reports).

---

## Alternative: Supervisor (If You Prefer)

**Install & Configure** (paths may vary under CloudLinux):

Create `/etc/supervisord.d/laravel-worker.ini`:

```ini
[program:laravel-worker]
directory=/home/USERNAME/APP
command=/opt/cpanel/ea-php84/root/usr/bin/php artisan queue:work --sleep=3 --tries=3 --max-jobs=100 --max-time=3600
autostart=true
autorestart=true
user=USERNAME
numprocs=1
redirect_stderr=true
stdout_logfile=/home/USERNAME/APP/storage/logs/worker.log

```

Reload and start:

```bash
supervisorctl reread
supervisorctl update
supervisorctl status

```

Scale by increasing `numprocs` **gradually** and watching load.

---

## Performance & Safety Tips

- **Use Redis** for queues where possible (faster and more resilient than database-backed queues).
- **Limit concurrency**: start with 1 worker; add more only if CPU headroom exists.
- **Use flags wisely**:
  - `--sleep=3`: pause when the queue is empty.
  - `--tries=3`: fail fast on bad jobs.
  - `--max-jobs=100` & `--max-time=3600`: recycle workers to prevent memory leaks.
- **Monitor**:
  - `htop`, `atop`, or `glances` for live CPU/mem.
  - `iostat -x 1` for disk IO.
  - Laravel Horizon for queue visibility (if using Redis).

**Cache everything**:

```bash
php artisan optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache

```

---

## Troubleshooting Checklist

- ✅ Crontab has **no** `queue:work` lines.
- ✅ Only **one** scheduler cron per app.
- ✅ systemd/Supervisor shows the intended number of workers.
- ✅ Load averages settle close to your core count.
- ✅ `storage/logs/` contains no recurring fatal errors.
- ✅ Horizon (if used) shows steady throughput and no stuck jobs.

---

## FAQ

**Q: Can I run multiple workers?**  
A: Yes—but scale carefully. Start with 1, then add more services or increase `numprocs` while watching load.

**Q: Why not cron for `queue:work`?**  
A: Cron is designed for short-lived tasks. Queue workers are **long-lived**. Cron will spawn a new process every run, causing pile-ups.

**Q: Do I need Horizon?**  
A: Not required, but recommended if you use Redis. It gives great insight into job throughput and failures.

**Q: My load is still high after the fix—now what?**  
A: Profile your jobs (optimize code, batch work), add caching, upgrade CPU, or split heavy jobs onto a separate worker box.

---

## Wrap up

“**Hung Service Checks**” on cPanel usually means the **CPU is overwhelmed**—often by cron repeatedly starting new Laravel workers. The permanent solution is simple: **scheduler in cron**, **workers under systemd or Supervisor**, and **sensible worker limits**. Do that, and your server will breathe again.

---