php resource_error ai_generated partial

Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\ProcessOrder has been attempted too many times or run too long. The job may have previously timed out.

ID: php/laravel-queue-worker-memory-leak

Also available as: JSON · Markdown · 中文
78%Fix Rate
84%Confidence
1Evidence
2024-01-12First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Laravel 10 active
Laravel 11 active
PHP 8.1 active
PHP 8.2 active

Root Cause

A queue worker process exceeded the allowed memory limit (memory_limit) or the job's timeout (retry_after or --timeout), causing the job to be released and retried until it reaches the maximum attempts threshold.

generic

中文

队列工作进程超出了允许的内存限制(memory_limit)或任务的超时时间(retry_after或--timeout),导致任务被释放并重试,直到达到最大尝试次数阈值。

Official Documentation

https://laravel.com/docs/11.x/queues#max-attempts

Workarounds

  1. 70% success Increase PHP's memory_limit in php.ini or via ini_set() for the queue worker: memory_limit = 512M. Then restart the worker: php artisan queue:restart.
    Increase PHP's memory_limit in php.ini or via ini_set() for the queue worker: memory_limit = 512M. Then restart the worker: php artisan queue:restart.
  2. 75% success Add explicit garbage collection in the job's handle() method: unset($largeVariable); gc_collect_cycles(); Also ensure no circular references exist.
    Add explicit garbage collection in the job's handle() method: unset($largeVariable); gc_collect_cycles(); Also ensure no circular references exist.
  3. 85% success Use the --max-jobs option to restart the worker after a set number of jobs: php artisan queue:work --max-jobs=100. This prevents memory accumulation.
    Use the --max-jobs option to restart the worker after a set number of jobs: php artisan queue:work --max-jobs=100. This prevents memory accumulation.

中文步骤

  1. Increase PHP's memory_limit in php.ini or via ini_set() for the queue worker: memory_limit = 512M. Then restart the worker: php artisan queue:restart.
  2. Add explicit garbage collection in the job's handle() method: unset($largeVariable); gc_collect_cycles(); Also ensure no circular references exist.
  3. Use the --max-jobs option to restart the worker after a set number of jobs: php artisan queue:work --max-jobs=100. This prevents memory accumulation.

Dead Ends

Common approaches that don't work:

  1. 60% fail

    This only delays the problem; the underlying memory leak or timeout issue still exists, and the job will eventually fail again or consume excessive resources.

  2. 70% fail

    Disabling timeouts can cause workers to hang indefinitely, leading to resource starvation and blocking other jobs.

  3. 80% fail

    Restarting resets the worker state but does not fix the memory leak; the error will reoccur after enough jobs are processed.