Master memory management for Laravel queue workers and CLI tasks. Learn to identify leaks, set memory thresholds, and keep your production processes stable.
Previously in this course, we discussed profiling PHP execution to identify bottlenecks. Today, we shift our focus from execution speed to memory stability. When running Laravel queue workers or long-lived CLI tasks, memory leaks can silently accumulate, eventually leading to OOM (Out of Memory) crashes that destabilize your production environment.
Unlike a standard web request that spins up, executes, and terminates in milliseconds, a long-running CLI process stays alive for hours or days. In this lifecycle, any object referenced in a static variable, a long-lived service container binding, or a global array will remain in memory for the duration of the process.
If your code creates objects inside a loop without clearing them—or if you're using libraries that cache metadata in static properties—your memory footprint will grow monotonically. This is the hallmark of a memory leak in PHP.
Before you add restart thresholds, you must identify the source. If your worker's memory consumption follows a linear "sawtooth" pattern that never returns to a baseline, you have a leak.
memory_get_usage(): Inject this into your job's handle() method during development.htop or top: Monitor the Resident Set Size (RSS) of your specific worker process.Laravel provides a built-in safety net for this exact problem. Instead of trying to achieve "perfect" memory management, we use a "restart on limit" strategy.
When running your queue workers, you should always define a memory limit. This tells the worker: "If you exceed this amount of RAM, finish your current job, then kill yourself so the supervisor can spawn a fresh, clean process."
You can configure this globally or per-worker:
Bash# Start a worker that restarts if it hits 128MB php artisan queue:work --memory=128
If you are using Laravel Horizon for your queue management, define this in your config/horizon.php file under the environments section:
PHP'environments' => [ 'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default', 'imports'], 'balance' => 'auto', 'memory' => 128, #6A9955">// The magic threshold ], ], ],
Consider an importer job that processes thousands of rows. If you aren't careful, you might be keeping the entire collection of processed records in a static property.
PHPclass ProcessLargeImport implements ShouldQueue { #6A9955">// BAD: Static property grows indefinitely public static $processedItems = []; public function handle() { $item = $this->repository->getNext(); #6A9955">// This will eventually crash the worker self::$processedItems[] = $item; $item->process(); } }
To fix this, you must ensure that your memory is cleared after every job. If you find yourself needing to cache data across jobs, use Redis or a cache store rather than memory-resident arrays. For high-throughput scenarios, look into Laravel Octane Memory Management: Implementing Custom Object Pooling to recycle objects instead of leaking them.
memory_get_usage(true).memory_get_usage() > 1024 * 1024 * 10 (10MB), throw an exception or exit.--memory limit is at least 2-3x the size of your largest expected peak memory usage.php.ini: CLI memory limits are distinct from web memory limits. Check your php --ini output to ensure your CLI environment isn't restricted by a memory_limit that is lower than your worker threshold.public static properties. They are the most common source of leaks in long-running Laravel processes.Memory management in long-running processes is about containment. By monitoring your memory growth, using tools like Horizon to set strict memory thresholds, and avoiding the usage of static properties for state, you ensure your background workers remain stable under heavy load.
Up next: We will discuss how to write effective tests for your domain-driven components in Testing DDD Components.
Improve application performance by offloading heavy tasks to queues. Learn how to configure drivers, create job classes, and dispatch background jobs.
Read moreMaster scalable file uploads in Laravel. Learn to stream directly to S3 and process heavy files asynchronously to keep your application fast and memory-efficient.
Memory Management in Long-Running Processes
Custom Middleware Development
Database Connection Pooling
Handling Large Data Exports
Security Header Configuration
Database Sharding Concepts
Real-time Data Synchronization
Database Deadlock Prevention
Managing Third-Party API Integrations