- Managed queues (recommended), where Laravel Cloud provisions all the infrastructure needed to run a queue (compute, driver, and monitoring) and runs and scales the workers for you
- Worker clusters, where you manage
queue:workyourself on compute that is separate from your web traffic
php artisan queue:work against your application’s own queue driver (redis, database, your own SQS, or whatever your configured connection points at) and scales its worker count on job latency and queue pressure. Neither replacement is a one-to-one copy of that.
- A managed queue swaps your queue driver for one that Laravel Cloud provisions, then scales workers on the work waiting to be processed, including down to zero.
- A worker cluster keeps your driver and your
queue:workcommand exactly as they are, but scales on CPU and memory rather than on queue depth.
cloud connection and let the old connection drain before deleting the queue cluster. A worker cluster keeps the existing connection, so both clusters process its backlog until you delete the queue cluster.
Deleting the queue cluster is the one step you cannot undo. Before you do it, confirm all of the following:
- The replacement has processed a test job on every queue name the cluster served.
queue:monitorreports zero jobs on the old connection, including delayed jobs.- Failed jobs have been retried or deleted. A retried failed job is re-dispatched onto the connection recorded on it, so a retry after the cutover can land on the old connection with no worker left to run it.
- You have a copy of the queue cluster’s settings, since they are discarded with it.
Before you start
Open the queue cluster on your environment’s infrastructure canvas and write down its settings: the connection, the queue name or names it processes (a single queue cluster may serve a comma-separated list such asemails,notifications), and the worker options (backoff, sleep, rest, timeout, tries, max-jobs, max-time, and force). You will recreate these on the replacement, and they disappear with the queue cluster when it is deleted.
If you are not sure which queue names your application dispatches to, check the queue value of your connection in config/queue.php, then search your code for explicit queue names:
Then check the one thing that decides your path: whether your jobs depend on behavior specific to your current driver. Redis-specific queue features, per-job delays longer than 15 minutes, and strict ordering are the usual reasons to keep the driver. Queue clusters and worker clusters are available on the same plans, so plan is not a factor.
Managed queues are the right destination for most applications, and the one we recommend. Choose a worker cluster when your application must keep its current driver.
Move to a managed queue
1
Check the requirements
Managed queues require Laravel 11.55.0, 12.63.0, 13.19.0, or newer, with
aws/aws-sdk-php in your composer.json. Laravel Cloud reads your composer.lock at deploy time, so update the framework, commit the lock file, and deploy before you create the queue. A deployment that creates a managed queue without the SDK fails with a clear error. Symfony applications are supported via laravel/symfony-on-cloud. See Requirements.2
Create one managed queue per queue name
Click Add compute on the canvas toolbar, then Managed queue. Each managed queue handles exactly one Laravel queue name, so a queue cluster processing
emails,notifications becomes two managed queues, one named emails and one named notifications. Name each queue exactly as your application dispatches to it. The first managed queue you create becomes the environment’s default and receives any job dispatched without a queue name; see Setting a default queue.For memory, start close to the queue cluster’s compute size (256 MiB covers typical email, webhook, and record-update jobs) and adjust after watching the Memory chart on the Queues dashboard. For the worker autoscaling range, set the maximum by how much parallelism your database and third-party APIs can absorb, not by the queue cluster’s worker count. The two scale differently, so that number does not carry over. Queue and worker allowances vary by plan; see Managed queues for the current limits.3
Decide what happens to QUEUE_CONNECTION
Deploying a managed queue sets The details are in Queue connection.
QUEUE_CONNECTION=cloud for the environment. From that deployment on, every job dispatched without an explicit connection, including the jobs your queue cluster processes today, goes to managed queues. This is usually exactly what you want. If some jobs must stay on your previous driver, set QUEUE_CONNECTION back to it as a custom environment variable and dispatch managed-queue jobs on the cloud connection explicitly:4
Deploy and verify
Deploy the environment. Laravel Cloud provisions each queue and starts its worker pool. Dispatch a test job to every queue name and watch it process on the Queues dashboard under the environment’s Monitoring tab. Because the default connection switched with this deployment, the queue cluster stops receiving new jobs unless you pinned
QUEUE_CONNECTION in the previous step or jobs explicitly target the old connection. When neither applies, it works through only the jobs already on the old connection.5
Drain and delete the queue cluster
Leave the queue cluster running until the old connection is empty. Check from the Commands tab, substituting your own connection and queue names:The reported size includes delayed and reserved jobs, so zero means genuinely done. Delayed jobs and pending retries are the ones most likely to be left behind, since they sit on the old connection until their time comes.Then remove the queue cluster from the infrastructure canvas and deploy. Deleting it stops its workers immediately and discards its settings. Any job still on the old connection at that point is never processed.
QUEUE_CONNECTION to your previous driver as a custom environment variable and deploy. New jobs return to the old connection and the queue cluster picks them up again. Jobs already sitting on a managed queue stay there until its workers finish them; deleting the managed queue discards them. Remove the managed queue from the canvas too if you are not keeping it.
What behaves differently
A managed queue is not the same queue your cluster was working. Expect these differences, all covered in more depth under Limitations:- Standard queues deliver each job at least once with best-effort ordering. Design jobs to tolerate a second run, or create a FIFO queue for order-sensitive work.
- Delays are capped at 15 minutes on standard queues, and FIFO queues do not support per-job delays at all. Search your code for
->delay()andrelease()calls beyond that window before you migrate. - Jobs on the Flex class should finish within 90 seconds. Longer jobs belong on the Pro class, which has no fixed limit.
- The
queue:failed,queue:retry, andqueue:clearArtisan commands are not supported. Failed jobs are listed, retried, and deleted from the Queues dashboard or the Laravel Cloud API instead.
Move to a worker cluster
A worker cluster runs yourqueue:work command verbatim against your own driver, so nothing changes in your application. What you give up is the queue cluster’s latency-based scaling, which this path replaces with CPU and memory scaling.
1
Create the worker cluster
On the infrastructure canvas, click Add worker cluster. Choose a compute size in the same range as the queue cluster’s, since it will run the same jobs, and size it independently of the app cluster: a worker cluster never serves HTTP traffic. See Worker clusters.
2
Add a worker background process
Click the new Worker cluster, then in the Background processes section click New background process. Copy the queue cluster’s connection, queue names, and worker options (backoff, sleep, rest, timeout, tries, and force) into the worker form one-to-one. The queue field accepts the same comma-separated list, so one background process replaces one queue cluster. If your queue cluster relied on max-jobs or max-time, which the worker form does not expose, use the Custom worker tab instead and enter the full See Custom background processes for how custom workers behave.
php artisan queue:work command with those flags:3
Set processes and scaling
Each background process runs between 1 and 10 processes, and that number is multiplied by the cluster’s replica count. A worker with 4 processes on a cluster running 3 replicas is 12
queue:work processes hitting your database at once. Choose a process count that fits comfortably in one replica’s memory, then pick a fixed replica count or a minimum and maximum range under Autoscaling. The maximum replica count depends on your plan.4
Decide whether it sleeps
If the app cluster scales to zero, the worker cluster can either stay awake at all times or sleep alongside the app cluster (Flex compute only, since Pro does not scale to zero). A sleeping worker cluster stops when the app cluster’s sleep timeout elapses, even if a job is still running, so keep the worker cluster awake when it runs your queue workers. See Queue workers and Scale to Zero.
5
Deploy and verify
Deploy the environment. Both the queue cluster and the worker cluster now consume the same queues from your driver, which is safe: each job is reserved by one worker or the other. Watch the worker’s output in the Logs tab and its CPU and memory on the Metrics tab, and confirm jobs complete. Laravel Cloud restarts a background process automatically if it exits, and
queue:restart is not needed after deployments.6
Drain and delete the queue cluster
Once the worker cluster is keeping up, remove the queue cluster from the canvas and deploy. Because both clusters read the same queue, no jobs are stranded; the worker cluster simply takes over the whole backlog. Deleting the queue cluster stops its workers immediately and discards its settings, so confirm the worker background process is saved with everything you copied in step 2 before you delete.
retry_after window and picked up by the queue cluster, so nothing is lost, though those jobs run twice.
Worker clusters scale on CPU and memory, never on queue depth. A backlog of cheap jobs that mostly wait on the network may never push CPU high enough to add a replica, so a queue cluster that “just kept up” can fall behind on a worker cluster with the same size. To compensate, set the minimum replica count for your peak rather than your average, or, on the Business and Enterprise plans, use scheduled autoscaling to raise the minimum ahead of known bursts. If you want scaling driven by the work waiting, that is what managed queues do.

