DEV Community

Meera9
Meera9

Posted on

When My Laravel Queue Kept Stopping, the Queue Wasn't the Real Problem

Summer Bug Smash: Smash Stories 🐛🛹

This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry.

Project Overview

I was working on a Laravel application running on a cPanel server where background processing was handled through Laravel queues and Redis.

The application also had an integration with Make.com. Make.com periodically sent requests to the Laravel application, which then dispatched background jobs for processing.

The overall flow looked like this:

Make.com
   |
   | API requests
   v
Laravel application
   |
   v
Redis
   |
   v
Laravel Queue Worker
   |
   v
Background processing
Enter fullscreen mode Exit fullscreen mode

The setup worked, but under certain conditions the queue would stop processing and eventually the Make.com requests would start failing.

At first, I thought I had a Laravel queue problem.

It turned out to be a much more interesting infrastructure problem.


Bug Fix or Performance Improvement

The first problem: nohup was not enough

Initially, I was running the Laravel queue worker using nohup.

The idea was simple: start the worker in the background and let it continue running after the terminal session ended.

That worked until the server or cPanel environment restarted.

After a restart, the nohup process was gone.

So the situation became:

Server restart
     |
     v
nohup queue worker disappears
     |
     v
Redis still contains jobs
     |
     v
No worker is processing them
     |
     v
Queue starts growing
Enter fullscreen mode Exit fullscreen mode

I had to manually restart the worker.

That was the first problem I fixed.

Moving the worker to cPanel Cron

Instead of depending on a manually started long-running process, I changed the setup so cPanel Cron would execute the queue worker.

The important part of the command was:

cd /home/user/laravel && \
/bin/flock -n storage/framework/queue-worker.lock \
php artisan queue:work redis \
--queue=default \
--stop-when-empty \
--sleep=3 \
--tries=3 \
--timeout=120 \
--max-time=120
Enter fullscreen mode Exit fullscreen mode

Using flock was important because I did not want multiple Cron executions accidentally starting competing workers.

--stop-when-empty also made sense for this Cron-based model: the worker could process the available jobs and exit instead of relying on a permanently running process.

At this point, the queue was much more resilient.

But I had not solved the entire problem yet.


The second problem: Make.com requests started timing out

After moving the queue execution to Cron, I noticed another failure mode.

When the server became unhealthy or PHP requests became slow, Make.com started reporting high request timeouts.

This was confusing because Redis itself was working.

The queue connection was working.

The Laravel application could communicate with Redis.

So I started looking at the server rather than assuming the queue was broken again.

The investigation eventually led me to PHP-FPM.


Finding the PHP-FPM bottleneck

The server had approximately:

RAM: ~65 GB
CPU: 20 cores
Enter fullscreen mode Exit fullscreen mode

But PHP-FPM had very conservative worker settings.

The configuration I found was:

pm.max_children = 5
pm.max_requests = 20
pm.process_idle_timeout = 10
Enter fullscreen mode Exit fullscreen mode

That immediately became interesting.

The server had a lot of available memory, but PHP-FPM was configured to allow only a small number of child processes.

Under concurrent requests, that meant requests could wait for an available PHP-FPM worker.

The simplified flow looked like this:

Multiple requests arrive
        |
        v
PHP-FPM
        |
        +--> Worker 1
        +--> Worker 2
        +--> Worker 3
        +--> Worker 4
        +--> Worker 5
        |
        v
Additional requests wait
        |
        v
Request latency increases
        |
        v
Make.com timeout
Enter fullscreen mode Exit fullscreen mode

The important lesson was that a server having plenty of RAM does not automatically mean the application is configured to use its available resources effectively.


GIF: The original failure

Show a short recording of:

  1. Make.com scenario starting
  2. HTTP request being sent
  3. Long wait
  4. Request timeout/failure
  5. Laravel/server becoming slow

Code

Before: PHP-FPM configuration

The original settings were:

pm.max_children = 5
pm.max_requests = 20
pm.process_idle_timeout = 10
Enter fullscreen mode Exit fullscreen mode

After: PHP-FPM configuration

I increased the PHP-FPM capacity after checking the server resources and workload.

pm.max_children = [YOUR_ACTUAL_FINAL_VALUE]
pm.max_requests = [YOUR_ACTUAL_FINAL_VALUE]
pm.process_idle_timeout = [YOUR_ACTUAL_FINAL_VALUE]
Enter fullscreen mode Exit fullscreen mode

Replace the values above with the exact production values you actually deployed. I am intentionally not inventing them here.

The important change was not simply "make the numbers bigger."

The goal was to match PHP-FPM's process capacity to the actual server resources and workload instead of running a 65 GB / 20-core server with extremely conservative worker limits.


Queue worker configuration

I also changed the queue execution model from a manually started nohup process to a Cron-managed worker.

cd /home/user/laravel-main && \
/bin/flock -n storage/framework/queue-worker.lock \
php artisan queue:work redis \
--queue=default \
--stop-when-empty \
--sleep=3 \
--tries=3 \
--timeout=120 \
--max-time=120
Enter fullscreen mode Exit fullscreen mode

The lock prevents overlapping Cron executions from starting multiple copies of the same worker.


GIF: Queue recovery

Show:

Cron
  ↓
Laravel queue:work
  ↓
Redis
  ↓
Job processing
  ↓
Queue becomes empty
Enter fullscreen mode Exit fullscreen mode

My Improvements

The biggest improvement was not a single configuration value.

It was changing how I diagnosed the problem.

Initially, my mental model was:

Make.com request fails
        |
        v
Laravel queue is broken
Enter fullscreen mode Exit fullscreen mode

That turned out to be too narrow.

I started checking each layer separately:

Make.com
   |
   v
Laravel API
   |
   v
PHP-FPM
   |
   v
Redis
   |
   v
Queue Worker
   |
   v
Background Job
Enter fullscreen mode Exit fullscreen mode

This helped separate two different problems.

Problem 1

The queue worker was dependent on nohup.

A server restart killed the worker.

Fix

Move queue execution to cPanel Cron and use flock to prevent overlapping workers.


Problem 2

The server could become slow enough that Make.com API requests timed out.

Investigation

Redis was reachable.

The queue connection worked.

The server had significant unused RAM.

PHP-FPM, however, had very conservative process limits.

Fix

Tune PHP-FPM according to the actual server capacity and workload.


GIF: Finding the real bottleneck

A useful GIF here would show:

BEFORE

pm.max_children = 5
pm.max_requests = 20
pm.process_idle_timeout = 10

              ↓

Server investigation

              ↓

AFTER

pm.max_children = [ACTUAL VALUE]
pm.max_requests = [ACTUAL VALUE]
pm.process_idle_timeout = [ACTUAL VALUE]
Enter fullscreen mode Exit fullscreen mode

What I learned

The biggest lesson from this bug was:

A queue problem isn't always a queue problem.

When a background job stops processing, it is tempting to immediately investigate Redis or Laravel's queue configuration.

But the complete path matters.

A queue-based application depends on multiple layers:

External automation
       ↓
HTTP server
       ↓
PHP-FPM
       ↓
Laravel
       ↓
Redis
       ↓
Queue worker
       ↓
Job
Enter fullscreen mode Exit fullscreen mode

If any layer becomes a bottleneck, the symptom can appear somewhere completely different.

In my case, the symptoms looked like:

Make.com
   ↓
Timeout
Enter fullscreen mode Exit fullscreen mode

and:

Laravel
   ↓
Queue not processing
Enter fullscreen mode Exit fullscreen mode

But the investigation revealed two separate reliability issues:

1. Worker lifecycle
   └── nohup process disappeared after restart

2. Request capacity
   └── PHP-FPM worker configuration was too conservative
Enter fullscreen mode Exit fullscreen mode

Fixing both made the system considerably more resilient.


Before vs After

Before

Make.com
   |
   v
Laravel API
   |
   v
PHP-FPM
   |
   |  Only a small number of workers
   v
Requests wait / become slow
   |
   v
Make.com timeout


Queue:

nohup
  |
  v
Queue worker
  |
  X
Server restart
  |
  v
Worker disappears
Enter fullscreen mode Exit fullscreen mode

After

Make.com
   |
   v
Laravel API
   |
   v
PHP-FPM
   |
   v
Laravel
   |
   v
Redis
   |
   v
Cron-managed queue worker
   |
   v
Background processing
Enter fullscreen mode Exit fullscreen mode

The infrastructure became easier to reason about because the queue worker no longer depended on a manually maintained nohup process.


Results

After the changes, the queue worker no longer depended on manually restarting nohup after a server restart.

The PHP-FPM configuration was also adjusted to better match the server's available resources and the application's workload.

Most importantly, I stopped treating the queue as an isolated component.

The queue, PHP-FPM, Laravel API, Redis, Cron, and external automation were all part of the same system.

That was the real bug to fix.


Best Use of Sentry

Best Use of Google AI

Top comments (0)