Back to Blog
Bug Fixes•5 min read

Fix Laravel Queue Jobs Not Processing After Deployment

LaravelQueuesDeployment

In this guide

Recover Laravel queue jobs after deployment by checking the connection, queue name, workers, cached configuration, failed jobs, and restart behavior.

Laravel queue jobs not processing after deployment usually require checking the worker, connection, queue name, and deployed configuration together. Confirm that jobs are actually dispatched, inspect failed jobs, and restart long-running workers through the process manager. Do not delete the queue to hide a growing backlog.

Is the job missing, waiting, running, or failing?

An illustrative CRM accepts a customer enquiry and queues a follow-up notification. The website reports success, but no message arrives after a release. That symptom alone does not identify the fault. The job may never have been dispatched, may be waiting on a different queue, or may be failing when contacting the messaging provider.

Trace one non-sensitive test record through dispatch, queue storage, worker logs, and the final action. Keep its correlation ID and timestamps. Avoid repeatedly creating real customer notifications while investigating. If the queue handles consequential actions, use a staging destination or a dedicated harmless diagnostic job.

Step 1: verify the connection and named queue

Compare the application's effective queue connection with the worker command. A job dispatched to Redis on the notifications queue will not be consumed by a worker watching the database connection's default queue. Review both application configuration and the process manager definition from the deployed release.

Check cached configuration through the application's supported inspection workflow without dumping secrets. After environment changes, regenerate configuration as part of deployment and restart workers so the intended values take effect. An edited environment file does not prove that an already-running process has reloaded it.

Step 2: inspect worker state and failed jobs

Use commands supported by the Laravel version installed in your project. These examples are diagnostic starting points; the worker command assumes Redis and a queue named notifications. Run a foreground worker only in a controlled environment where consuming those jobs is safe.

bash
# Inspect failures before retrying anything.
php artisan queue:failed

# Controlled diagnostic worker for this connection and queue:
php artisan queue:work redis --queue=notifications --once --tries=3 --timeout=60

# During a managed deployment, request graceful worker exit:
php artisan queue:restart

# Inspect the configured process manager:
supervisorctl status

Read the first useful exception, not just the final retry count. A missing class after a release, an unavailable Redis service, and a provider authentication failure require different fixes. Record the job's actual exception and deployment context. Increasing attempts without addressing the cause can amplify an external outage.

Step 3: restart the process that runs the current release

Queue workers remain alive across jobs. A deployment that replaces files without refreshing workers can leave old code running. Request graceful restart and confirm that Supervisor, systemd, your container orchestrator, or another process manager starts replacement workers from the correct release directory.

The restart signal also needs to reach workers through the configured cache. Check for mismatched cache settings or namespaces when a restart command appears to do nothing. Compare the worker's operating user, PHP binary, directory, and environment with the web process. An SSH session can run a different runtime from the managed worker.

If the application uses Horizon or a managed queue platform, follow that system's deployment lifecycle instead of layering an unrelated manual worker on top. The goal is one understandable ownership model for worker processes, logs, restarts, and failures. Two competing process definitions can make an intermittent incident harder to reproduce.

Step 4: check timeouts, retries, and transaction timing

Worker timeout should be shorter than the connection's retry-after visibility setting where that configuration applies. Otherwise a job may become available to another worker before the first execution ends. External API timeouts should also fit within the job budget. Verify the actual driver's semantics rather than assuming every queue provider behaves identically.

If a job reads a record created in a database transaction, dispatching it before commit can expose a missing record to a fast worker. Use the framework's after-commit behavior where appropriate. Keep jobs idempotent because retries and interruptions are part of queue operation; one business task must not become two notifications or invoices.

Step 5: recover a backlog without repeating completed work

  1. Fix the worker or dependency problem and run one harmless job through the complete path.
  2. Classify failed jobs by cause and business action. Identify which actions may already have succeeded before a timeout.
  3. Retry a selected, understood job before replaying a whole failure batch. Verify its downstream result.
  4. Increase consumption gradually while watching provider limits, database load, and the age of the oldest waiting job.
  5. Confirm a new deployment restarts workers correctly and that monitoring detects a stopped worker or growing backlog.

A dashboard showing zero failed jobs is insufficient if nothing is being consumed. Monitor queue age and successful completion along with failure counts. Decide who receives an alert, what evidence it includes, and how they distinguish a temporary provider outage from a broken release.

Should you switch the queue to synchronous mode?

Synchronous mode can help isolate behavior in a controlled development environment, but it changes where work runs and how long the web request takes. It does not repair production worker management. A slow provider call moved into a contact-form request can cause timeouts and repeated submissions instead of a visible queue backlog.

If a job succeeds synchronously but fails in the worker, compare process configuration, code version, credentials, permissions, and transaction timing. Use that difference as diagnostic evidence. Keep production recovery focused on the intended asynchronous architecture, with a process manager and observable completion. Document any temporary workaround, its owner, and the condition for removing it.

Read the Laravel queues introduction for the basic architecture, or the duplicate webhook guide for retry-safe event handling. If a production workflow keeps stalling, discuss a backend reliability review and share a redacted worker error.

Official references and further reading

Laravel: queue workers, failures, and deployment

Laravel: configuration caching

Supervisor: process configuration

Share this article:

Keep Reading

Ready to implement these ideas?

Discuss Your Project