Skip to main content
← All use cases

Laravel Queue Worker Timeout Monitoring

A queue worker can look healthy while still doing the wrong thing.

It may still be running in Supervisor or Horizon, but individual jobs can hang, hit timeout limits, or keep retrying until throughput drops to a crawl. By the time users notice, the queue is already behind.

What queue worker timeouts look like

The common failure modes are usually:

If you only watch whether the process exists, you miss the failure.

Why heartbeat checks are not enough

A heartbeat tells you a process reported in.

That is useful, but it does not tell you whether the worker is actually clearing the queue. A worker can ping successfully while the job queue grows, retries pile up, and the oldest job keeps getting older.

That is why timeout monitoring should include queue depth, failed jobs, and oldest job age, not just a single “still alive” signal.

What to monitor in Laravel

For queue worker timeouts, track:

If those signals rise together, your workers are probably hanging on a downstream dependency or a bad job configuration.

Example worker config

php artisan queue:work redis --sleep=3 --tries=3 --timeout=90 --max-time=3600

The important part is not the exact number. It is that your monitoring knows when jobs are nearing that limit and when the queue is not recovering after a restart.

How Crontinel helps

Crontinel watches cron runs, queue depth, failed jobs, and Horizon state.

That means a worker timeout does not stay buried inside logs. You get a visible alert when the queue stops moving, when failures spike, or when the worker pool stops recovering after a deploy.

See also

Start with one HTTP receipt

Five common runtimes post the same outcome body: curl, Node, Python, Sidekiq, and GitHub Actions. Laravel apps can add the Composer package for schedule, queue, and Horizon.

curl -X POST "$CRONTINEL_API_URL/api/v1/ingest/cron" \
  -H "Authorization: Bearer $CRONTINEL_INGEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{"command":"nightly-import","status":"completed","exit_code":0,"outcomes":{"metrics":{"processed_records":0}}}'