Skip to main content
This guide is for Laravel applications.
When you create a Laravel Cloud managed queue, you choose how much memory each worker receives. Flex workers support between 256 MiB and 2 GiB of memory, while Pro workers support up to 8 GiB. This is the only sizing decision required for a managed queue, and you can adjust the size with each deployment. This guide explains how to measure your jobs’ memory usage and choose an appropriate size. Sizing is always a per-queue exercise. Each managed queue processes exactly one Laravel queue name, so you are measuring the jobs that run on that particular queue: the jobs your application dispatches to it with ->onQueue(...), or every job dispatched without an explicit queue name if it is the environment’s default queue. Keep that boundary in mind throughout this guide, especially once you have more than one queue.

Start with your jobs

A worker’s memory needs are driven by what your job’s handle method loads into memory while it runs. Job payloads are capped at 1 MiB, so the payload itself is never the problem; the question is what the job pulls in while doing its work. Typical Laravel jobs, such as sending mail, firing notifications, processing webhooks, and updating records, use well under 100 MB, and the default 256 MiB size handles them comfortably. Jobs may require a larger size when they hydrate large sets of Eloquent models, read entire files into memory, generate exports or reports, manipulate images and video, or run machine learning inference.

Size for the largest job on the queue

Each worker processes one job at a time, and every job dispatched to a queue runs on a worker of that queue’s size. The memory size therefore needs to fit the hungriest job that will ever cross the queue, not the average one. When a job needs more memory than its worker has, it runs out of memory (often abbreviated “OOM”). The job typically fails with a PHP fatal error reporting that the allowed memory size was exhausted. The worker then restarts, and the job is redelivered to another worker. Redelivery does not resolve an undersized queue: the job fails on every attempt until it exhausts its retries and appears in failed jobs. An occasional restart is harmless, but a job class that consistently runs out of memory requires a larger queue size or its own queue.

Measure locally

For a quick estimate, run your worker in verbose mode while dispatching jobs locally:
In verbose mode, each completed job’s output line includes the worker’s current memory usage. This reflects the worker process as a whole rather than the individual job, but it gives you an immediate ballpark. By default, a worker only processes the default queue. If you are sizing another queue, dispatch your test jobs to that queue and start the worker with the matching option, such as php artisan queue:work -v --queue=invoices. Without the --queue option, you may measure the wrong jobs. For a true per-job reading, register a temporary listener in your AppServiceProvider’s boot method:
The queue worker resets PHP’s peak memory counter between jobs, so each log entry reflects the job’s peak memory usage. The JobAttempted event fires whether the job succeeds or fails. Dispatch a realistic sample of your heaviest jobs using realistic file sizes and production-like data volumes. After the worker processes them, review the peaks in your log.
Dispatch into a genuinely local environment. If your QUEUE_CONNECTION, database, mail driver, or API credentials point at shared or production services, a memory test can drop jobs onto a real queue, send real emails, or hit live APIs. Check your .env first and point anything live at a local or sandbox equivalent (for example, MAIL_MAILER=log).
Choose the smallest size that provides roughly 30% headroom above your largest peak. This headroom accommodates day-to-day variations in your data and the memory reserved for the worker runtime.

Let an AI agent measure it for you

An AI coding agent can perform the measurement for you. It can identify the queue you are sizing, verify that your local environment is safe, find and run the relevant jobs locally, and recommend a size or queue split.

Copy this prompt into your coding agent from your application's directory to measure your jobs and get a size recommendation.

Verify on Cloud

Local measurements provide a useful starting point, while production data confirms whether your queue is sized appropriately. Every environment with managed queues has a Queues tab with a Memory chart that displays peak worker memory usage over time. If peaks approach the top of the chart, increase the queue size. If they remain well below the limit, you may be able to decrease it. In a development or staging environment, you may start small, dispatch representative work, and increase the size if jobs fail. In production, start with more memory than you expect to need, run a full business cycle that includes scheduled work such as nightly imports or reports, and then reduce the size while keeping a comfortable margin below the limit. Workers are billed per second while running, so temporarily allocating additional memory typically costs less than diagnosing out-of-memory failures after launch. The signals of an undersized queue are a “Managed queue crashed and restarted” notification, fatal errors in your logs reporting exhausted memory, or jobs exhausting their retries without a clear exception.

Split queues by memory profile

If nine of your job classes peak under 100 MB and one PDF-processing job needs 4 GiB, a single queue forces every job onto 4 GiB workers. Instead, create a smaller queue for most jobs and a larger queue for the resource-intensive job, which you may dispatch using ->onQueue('heavy'). Each managed queue is sized independently, so most of your work runs on smaller, less expensive workers. The larger workers are billed only while the resource-intensive job runs. Before allocating more memory, consider reducing the job’s memory usage. Process large datasets with chunked queries or LazyCollection instead of loading entire tables, stream files to object storage instead of reading them entirely into memory, or split one large job into several smaller jobs that can run across multiple workers. Each worker’s temporary disk scales with its memory (512 MiB of disk per 1 GiB of memory), so a job that stages large files may need a larger size for disk capacity rather than memory. See Filesystem for details. For per-job timing and failure analytics across your entire application, consider pairing managed queues with Laravel Nightwatch.