> ## Documentation Index
> Fetch the complete documentation index at: https://cloud.laravel.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Managed Queues

> Process Laravel and Symfony jobs with fully managed queues.

## Introduction

Background jobs allow your application to defer slow or expensive work, such as sending email, generating PDFs, calling external APIs, or processing media, so that it can respond to web requests quickly.

Managed queues are available for Laravel and Symfony applications. To run custom background processes on any supported runtime, see [Workers](/docs/workers).

Managed queues isolate background jobs from your web traffic and run them on dedicated workers that scale with the work waiting to be processed. Flex workers scale to zero when idle, so you pay for compute only while jobs run. The Queues dashboard provides metrics, failed-job visibility, and retry controls.

## Managed queues vs. workers

Managed queues are the preferred choice for all new and existing Laravel and Symfony applications. Laravel Cloud provisions and operates the queue infrastructure, so you do not need to manage queue workers or drivers yourself.

Use [Workers](/docs/workers) when your application needs a custom long-running process or must continue using a self-managed queue driver, such as Redis or a database queue. Workers are available for every supported runtime, but you configure the command, process count, autoscaling, and operational behavior yourself.

## Managed queues

Each managed queue has its own worker pool, memory allocation, and autoscaling range, and is provisioned in its environment's region.

<Frame>
  <img src="https://mintcdn.com/cloud/Li3n8XJc4a7Ik1xC/images/managed-queue-create-dropdown.png?fit=max&auto=format&n=Li3n8XJc4a7Ik1xC&q=85&s=2ab773512f0e1ecd18f62b5370991537" alt="A managed queue being created" width="1200" height="969" data-path="images/managed-queue-create-dropdown.png" />
</Frame>

The number of queues available is based on your plan and applies to each environment:

| Plan | Managed queues per environment |
| - | - |
| Starter | 1 |
| Growth | 10 |
| Business | 50 |
| Enterprise | 50 |

Business and Enterprise organizations that need more queues per environment may [contact support](/docs/support) to raise this limit.

If you are on the Growth plan and need more queues per environment, [contact support](/docs/support) to [request a higher limit](/docs/pricing#raising-plan-limits).

<Tip>
  A single queue is sufficient for most applications. Create separate queues when workloads need different memory allocations or autoscaling ranges.
</Tip>

## Configure managed queues

### Creating a managed queue

Open your environment, click **Add compute** on the canvas toolbar, then **Managed queue**. Provide a queue name, choose its [queue type](#queue-types), memory allocation, and [worker autoscaling range](#worker-autoscaling), then deploy the environment.

Once deployed, Laravel Cloud creates the queue, configures access from your application, and starts its worker pool. Queue names may contain letters, numbers, hyphens, and underscores, and must be 39 characters or fewer, including the `.fifo` suffix for FIFO queues.

Each managed queue handles one queue name. The first queue you create becomes the environment's default queue. You can select **Set as default** from a queue's canvas menu to change it.

### Queue types

Each managed queue is either a standard queue or a FIFO queue. You choose the type when creating the queue and cannot change it afterward.

**Standard queues** provide at-least-once delivery with best-effort ordering and support per-job delays of up to 15 minutes. They are the right choice for most workloads.

**FIFO queues** deliver jobs in dispatch order and deduplicate jobs on arrival. They suit order-sensitive workloads such as payment processing and ledger updates. FIFO queues do not support per-job delays and have a small operations premium.

Laravel Cloud appends `.fifo` to every FIFO queue name. For example, a queue named `orders` becomes `orders.fifo`. A standard `orders` queue and a FIFO `orders.fifo` queue may exist in the same environment.

### Compute classes

Every managed queue runs on either the Flex or Pro compute class:

| | Flex | Pro |
| - | - | - |
| Scaling floor | Scales to zero | Always on, with at least one worker |
| Memory sizes | 256 MiB to 2 GiB | 256 MiB to 8 GiB |
| vCPU | Up to 1 | Up to 4 |
| Job runtime | Up to 90 seconds | No fixed limit |
| Price | Starts at \$0.00000152 per second | Starts at \$0.00000183 per second |

Pro sizes are priced at a 20% premium over the equivalent Flex size. Flex is the default and works well for spiky or idle-heavy workloads. Pro is appropriate for steady throughput and for jobs that exceed Flex's runtime or memory limits. Pro is available on the Growth, Business, and Enterprise plans. Enterprise customers on [Private Cloud](/docs/private-cloud) can use dedicated Pro sizes up to 16 GiB.

### Memory allocation

Each managed queue worker runs on an instance with configurable memory, and CPU scales proportionally with the selected size. The default, **256 MiB**, is sufficient for typical jobs such as sending email, processing webhooks, updating records, and light data transformation.

| Plan | Flex | Pro |
| - | - | - |
| Starter | 256 MiB to 2 GiB | Not available |
| Growth | 256 MiB to 2 GiB | 256 MiB to 8 GiB |
| Business | 256 MiB to 2 GiB | 256 MiB to 8 GiB |
| Enterprise | 256 MiB to 2 GiB | 256 MiB to 16 GiB |

If a job exceeds its worker's memory allocation, the worker restarts and Laravel Cloud redelivers the job. The failure usually appears as a PHP fatal error reporting that the allowed memory size was exhausted. Check the **Memory** chart on the Queues dashboard when workers repeatedly restart.

See the [queue worker memory sizing guide](/docs/knowledge-base/sizing-queue-worker-memory) for guidance on selecting a size.

<Note>Managed queue sizes are independent of App and worker cluster sizes. For queues created before Flex and Pro, see [Upgrading from earlier managed queues](#upgrading-from-earlier-managed-queues).</Note>

### Worker autoscaling

Each queue scales between a configured minimum and maximum number of workers. The lowest allowed minimum depends on the queue's [compute class](#compute-classes). Choose a maximum that your database, APIs, and other downstream systems can handle in parallel.

<Frame>
  <img src="https://mintcdn.com/cloud/MkfTsQSKGENWqY-2/images/managed-queue-autoscaling.png?fit=max&auto=format&n=MkfTsQSKGENWqY-2&q=85&s=8739c446dcc7a71be19c10fcc1205afd" alt="Configuring a managed queue's worker autoscaling" width="1298" height="1335" data-path="images/managed-queue-autoscaling.png" />
</Frame>

| Plan | Maximum workers per queue |
| - | - |
| Starter | 3 |
| Growth | 100 |
| Business | 500 |
| Enterprise | 1,000 |

Business and Enterprise organizations that need more workers per queue may [contact support](/docs/support) to raise this limit.

If you are on the Growth plan and need more workers per queue or larger [worker memory sizes](#memory-allocation), [contact support](/docs/support) to [request higher limits](/docs/pricing#raising-plan-limits).

Laravel Cloud measures queue depth and job duration to add and remove workers, removing them gradually as the queue drains.

**Scheduled autoscaling.** Managed queues also support scheduled autoscaling, which temporarily changes the minimum and maximum worker count on a one-time or recurring schedule. Scheduled overrides follow the same rules as [scheduled autoscaling](/docs/compute#scheduled-autoscaling) for compute clusters.

**Advanced settings.** Organizations with the advanced managed queues entitlement can override visibility and graceful shutdown timeouts from a queue's **Advanced** tab. Flex queues cannot extend the graceful shutdown timeout beyond 90 seconds. Most applications should use Laravel Cloud's defaults.

## Connect your application

<Tabs>
  <Tab title="Laravel">
    ### Requirements

    Managed queues require Laravel 11.55.0, 12.63.0, 13.19.0, or newer and the `aws/aws-sdk-php` package in your `composer.json`:

    ```sh theme={null}
    composer update laravel/framework
    composer require aws/aws-sdk-php
    ```

    ### Queue connection

    When you deploy a managed queue, Laravel Cloud sets `QUEUE_CONNECTION=cloud` for the environment. Jobs dispatched without an explicit connection use the managed queue.

    <Warning>
      Any job dispatched without an explicit connection, including jobs previously processed with the `database`, `redis`, or another driver, routes to a managed queue once one exists in the environment.
    </Warning>

    To continue using another driver for some jobs, set `QUEUE_CONNECTION` to that driver and dispatch managed-queue jobs explicitly with `->onConnection('cloud')`. Laravel applications that use the default `database` driver are the most likely to be affected.

    ### Setting a default queue

    The default managed queue receives jobs dispatched without an explicit queue name. For example, `dispatch(new SendEmail)` uses the default queue rather than a queue literally named `default`. You may rename the default queue without changing these dispatch calls.
  </Tab>

  <Tab title="Symfony">
    ### Requirements

    Symfony applications use the [`laravel/symfony-on-cloud`](https://github.com/laravel/symfony-on-cloud) package, which provides a `cloud` Messenger transport:

    ```sh theme={null}
    composer require laravel/symfony-on-cloud
    ```

    Register its bundle in `config/bundles.php`:

    ```php theme={null}
    return [
        // ...
        Laravel\Cloud\Symfony\LaravelCloudBundle::class => ['all' => true],
    ];
    ```

    <Note>The package does not ship a Symfony Flex recipe, so register the bundle manually.</Note>

    ### Routing messages

    The package provides a `cloud` Messenger transport with no DSN configuration required. Route messages to it in `config/packages/messenger.yaml`:

    ```yaml theme={null}
    framework:
        messenger:
            routing:
                '*': cloud
    ```

    If your application uses the conventional `async` transport, Laravel Cloud injects `MESSENGER_TRANSPORT_DSN=laravel-cloud://managed-queue` so it works without changes.

    ### Multiple queues, FIFO, and retries

    Use `CloudQueueStamp` to dispatch a Symfony message to a named queue. Without a stamp, messages use the environment's default queue:

    ```php theme={null}
    use Laravel\Cloud\Symfony\Queue\Messenger\CloudQueueStamp;
    use Symfony\Component\Messenger\MessageBusInterface;

    $bus->dispatch(new ProcessReport($report), [new CloudQueueStamp('critical')]);
    ```

    Use `CloudFifoStamp` with a `.fifo` queue when you need to set its ordering or deduplication key:

    ```php theme={null}
    use Laravel\Cloud\Symfony\Queue\Messenger\CloudFifoStamp;
    use Laravel\Cloud\Symfony\Queue\Messenger\CloudQueueStamp;

    $bus->dispatch(new ProcessOrder($order), [
        new CloudQueueStamp('orders.fifo'),
        new CloudFifoStamp(
            messageGroupId: 'customer-'.$order->customerId,
            messageDeduplicationId: 'order-'.$order->id,
        ),
    ]);
    ```

    On a standard queue, `CloudMessageGroupStamp` enables [SQS fair queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-fair-queues.html), so one noisy tenant does not starve the others. Unlike FIFO, the group ID does not impose ordering or deduplication.

    ### Delays and retries

    A `DelayStamp` on a standard queue maps to an SQS per-message delivery delay, capped at 15 minutes. Requesting a longer delay throws. FIFO queues do not support per-message delays.

    Symfony Messenger controls retries for the `cloud` transport:

    ```yaml theme={null}
    framework:
        messenger:
            transports:
                cloud:
                    retry_strategy:
                        max_retries: 3
                        delay: 1000
                        multiplier: 2
                        max_delay: 0
    ```

    A message that exhausts its retries, or throws `UnrecoverableExceptionInterface`, is recorded as a failed job in the Laravel Cloud dashboard.

    ### Local development

    Override the `cloud` transport in your `dev` environment to process messages inline without SQS:

    ```yaml theme={null}
    when@dev:
        framework:
            messenger:
                transports:
                    cloud: 'sync://'
    ```

    See the [`laravel/symfony-on-cloud` documentation](https://github.com/laravel/symfony-on-cloud) for all stamps and configuration options.
  </Tab>
</Tabs>

## Operate managed queues

### How jobs are processed

Laravel Cloud long-polls each queue and delivers jobs directly to workers. Jobs are usually picked up within milliseconds when workers are running and within a second when a Flex queue wakes from zero. There is no polling interval to configure.

Laravel Cloud extends a job's visibility timeout in three-minute increments while it runs. If a worker crashes or stops before the job completes, the job is retried. Design jobs to tolerate at-least-once delivery.

When a worker must stop, Flex workers have 90 seconds and Pro workers have one hour to finish their current job. Run jobs that may exceed 90 seconds on Pro.

### Filesystem

Each managed queue worker has its own ephemeral filesystem. Every 1 GiB of worker memory provides 512 MiB of temporary disk space. Files are not shared between jobs and are reset whenever a worker is replaced. Use [Laravel Object Storage](/docs/resources/object-storage) for persistent files.

### Observability

The **Queues** dashboard, under an environment's **Monitoring** tab, shows job volume, processing duration, memory usage, active workers, and failed jobs for every managed queue. Failed jobs can be inspected, retried, or deleted from the dashboard or the Laravel Cloud API. Retries and deletions require edit access to the environment.

<Frame>
  <img src="https://mintcdn.com/cloud/fNYw_GQuZYjoktzH/images/queues-tab.png?fit=max&auto=format&n=fNYw_GQuZYjoktzH&q=85&s=574f7140ac59fc01a59dd649e8023e01" alt="The Queues dashboard showing per-queue metrics and failed jobs" width="2992" height="1348" data-path="images/queues-tab.png" />
</Frame>

<Frame>
  <img src="https://mintcdn.com/cloud/MkfTsQSKGENWqY-2/images/queue-failed-job.png?fit=max&auto=format&n=MkfTsQSKGENWqY-2&q=85&s=6cc5d01af116e16a39484d62eb829216" alt="Inspecting a failed job" width="2226" height="1580" data-path="images/queue-failed-job.png" />
</Frame>

Worker output is included in the environment's [Logs](/docs/logs) tab under **Monitoring**.

### Pausing and purging

Pause a queue from its canvas menu to stop processing while allowing in-flight jobs to finish. Laravel Cloud stops polling and scales workers to zero, so no worker or polling charges accrue while it is paused. New jobs remain in the queue until you resume it. The `queue:pause` Artisan command is not supported. Pause and purge actions require edit access to the environment.

Purging removes every waiting job and cannot be undone. It may take up to 60 seconds and does not affect jobs already being processed.

### Preview environments

Managed queues work in [preview environments](/docs/preview-environments). Each preview receives isolated queues and workers, billed like other preview resources.

## Pricing

Managed queues are billed for worker time and queue operations. Flex workers are billed only while running, while Pro workers are billed continuously. For example, a Flex queue that runs three workers for 20 minutes is billed for 3,600 worker-seconds.

Standard queue operations cost **\$1 per 1 million operations** and FIFO operations cost **\$1.10 per 1 million operations**. Dispatching, starting, and deleting a successful job each count as an operation. Long-running jobs record additional visibility-extension operations while they run. Payload-bearing dispatches and starts are measured in 64 KB chunks, and a job payload may be up to 1 MiB. Laravel Cloud's polling baseline is approximately \$0.13 per queue each month. See [Managed queues pricing](/docs/pricing#managed-queues) for current regional pricing and plan limits.

## Migration and compatibility

### Limitations

See [Queue types](#queue-types) for the delivery, ordering, and delay guarantees of standard and FIFO queues.

Laravel Horizon and the `queue:failed`, `queue:retry`, and `queue:clear` Artisan commands do not support managed queues. Use the Queues dashboard or Laravel Cloud API to manage failed jobs.

### Upgrading from earlier managed queues

The latest managed queue generation automatically manages polling, visibility, and shutdown timeouts. To upgrade an earlier queue, update Laravel to a supported version and commit the updated `composer.lock`, select a Flex or Pro size in the queue settings, and deploy. Your queue keeps its earlier runtime and settings until you select a new size.

After upgrading, its previous polling interval setting no longer appears, and its visibility and shutdown timeouts return to the defaults unless your organization has the advanced managed queues entitlement. Failed jobs carry over, but the queue cannot return to its earlier runtime.

Queues that have not been upgraded retain their current settings and pricing until the earlier generation is retired on **September 30, 2026**. Those queues stop processing after that date. Because the underlying SQS queue retains a message for at most 14 days, jobs that remain unprocessed for longer than 14 days are lost.

### Migrating from queue clusters

Queue clusters are deprecated and will be sunset on **September 30, 2026**. To move a queue cluster to managed queues, create a managed queue with the same queue name, choose an appropriate memory size and worker maximum, deploy, then verify jobs process through the Queues dashboard. Let the old queue drain before deleting its queue cluster. If a queue cluster processes several queue names, create a managed queue for each name.

For complete instructions, including migration to worker clusters, see [Migrate from queue clusters](/docs/knowledge-base/migrate-from-queue-clusters).

## Queue workers and Scale-to-Zero

When a Laravel environment can [scale to zero](/docs/compute#scale-to-zero), it wakes to process queued jobs. However, its App cluster stops when the sleep timeout elapses, even if a job is still running.

Use managed queues for queued jobs on environments that scale to zero. Their dedicated workers scale independently of your App cluster, so background processing is not interrupted when your application sleeps.
