Queued PDF generation | laravel-pdf | Spatie

 SPATIE

  Laravel PDF
==============

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-pdf](https://spatie.be/docs/laravel-pdf/v2)  Basic-usage  Queued PDF generation

 Version   v2   v1

 Other versions for crawler [v2](https://spatie.be/docs/laravel-pdf/v2) [v1](https://spatie.be/docs/laravel-pdf/v1)

- [ Introduction ](https://spatie.be/docs/laravel-pdf/v2/introduction)
- [ Support us ](https://spatie.be/docs/laravel-pdf/v2/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-pdf/v2/requirements)
- [ Installation &amp; setup ](https://spatie.be/docs/laravel-pdf/v2/installation-setup)
- [ Questions and issues ](https://spatie.be/docs/laravel-pdf/v2/questions-issues)
- [ Alternatives ](https://spatie.be/docs/laravel-pdf/v2/alternatives)
- [ Changelog ](https://spatie.be/docs/laravel-pdf/v2/changelog)
- [ About us ](https://spatie.be/docs/laravel-pdf/v2/about-us)

Basic usage
-----------

- [ Creating PDFs ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/creating-pdfs)
- [ Responding with PDFs ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/responding-with-pdfs)
- [ Formatting PDFs ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/formatting-pdfs)
- [ Saving PDFs to disks ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/saving-pdfs-to-disks)
- [ Queued PDF generation ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/queued-pdf-generation)
- [ Testing PDFs ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/testing-pdfs)
- [ Setting defaults ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/setting-defaults)

Drivers
-------

- [ Configuration ](https://spatie.be/docs/laravel-pdf/v2/drivers/configuration)
- [ Customizing Browsershot ](https://spatie.be/docs/laravel-pdf/v2/drivers/customizing-browsershot)
- [ Using the Cloudflare driver ](https://spatie.be/docs/laravel-pdf/v2/drivers/using-the-cloudflare-driver)
- [ Using the DOMPDF driver ](https://spatie.be/docs/laravel-pdf/v2/drivers/using-the-dompdf-driver)
- [ Generating PDFs on AWS Lambda ](https://spatie.be/docs/laravel-pdf/v2/drivers/generating-pdfs-on-aws-lambda)
- [ Using the Gotenberg driver ](https://spatie.be/docs/laravel-pdf/v2/drivers/using-the-gotenberg-driver)
- [ Using the WeasyPrint driver ](https://spatie.be/docs/laravel-pdf/v2/drivers/using-the-weasyprint-driver)
- [ Custom drivers ](https://spatie.be/docs/laravel-pdf/v2/drivers/custom-drivers)

Advanced usage
--------------

- [ Creating PDFs with multiple pages ](https://spatie.be/docs/laravel-pdf/v2/advanced-usage/creating-pdfs-with-multiple-pages)
- [ Using Tailwind ](https://spatie.be/docs/laravel-pdf/v2/advanced-usage/using-tailwind)
- [ Extending with Macros ](https://spatie.be/docs/laravel-pdf/v2/advanced-usage/extending-with-macros)

 Queued PDF generation
=====================

###  On this page

1. [ Basic usage ](#content-basic-usage)
2. [ Callbacks ](#content-callbacks)
3. [ Queue configuration ](#content-queue-configuration)
4. [ Saving to a disk ](#content-saving-to-a-disk)
5. [ Customizing the job ](#content-customizing-the-job)
6. [ Limitations ](#content-limitations)
7. [ Testing ](#content-testing)

PDF generation can be slow, especially with the Browsershot or Cloudflare driver. If you don't need the PDF immediately, you can dispatch the generation to a background queue using `saveQueued()`.

Basic usage
-----------------------------------------------------------------------------------------

```
use Spatie\LaravelPdf\Facades\Pdf;

Pdf::view('pdfs.invoice', ['invoice' => $invoice])
    ->format('a4')
    ->saveQueued('invoice.pdf');
```

This will render the HTML from the Blade view eagerly, then dispatch a queued job that generates the PDF and saves it to the given path.

Callbacks
-----------------------------------------------------------------------------------

You can chain `then()` and `catch()` callbacks to react to the job's success or failure:

```
Pdf::view('pdfs.invoice', ['invoice' => $invoice])
    ->saveQueued('invoice.pdf')
    ->then(fn (string $path, ?string $diskName) => Mail::to($user)->send(new InvoiceMail($path)))
    ->catch(fn (Throwable $e) => Log::error('PDF generation failed', ['error' => $e->getMessage()]));
```

The `then` callback receives the path the PDF was saved to and the disk name (or `null` for local saves). This makes it easy to retrieve the file afterwards:

```
->then(function (string $path, ?string $diskName) {
    $contents = $diskName
        ? Storage::disk($diskName)->get($path)
        : file_get_contents($path);
})
```

The `catch` callback receives the exception.

Queue configuration
-----------------------------------------------------------------------------------------------------------------

You can specify the connection and queue name directly:

```
Pdf::view('pdfs.invoice', $data)
    ->saveQueued('invoice.pdf', connection: 'redis', queue: 'pdfs');
```

Or use chained methods for full control — these are proxied to Laravel's `PendingDispatch`:

```
Pdf::view('pdfs.invoice', $data)
    ->saveQueued('invoice.pdf')
    ->onQueue('pdfs')
    ->onConnection('redis')
    ->delay(now()->addMinutes(5));
```

Saving to a disk
--------------------------------------------------------------------------------------------------------

When using `disk()`, the queued job will save the PDF to the specified disk:

```
Pdf::view('pdfs.invoice', $data)
    ->disk('s3')
    ->saveQueued('invoices/invoice.pdf')
    ->then(function (string $path, ?string $diskName) {
        $url = Storage::disk($diskName)->url($path);
        // ...
    });
```

Customizing the job
-----------------------------------------------------------------------------------------------------------------

You can replace the job class used by `saveQueued()` in your `config/laravel-pdf.php`:

```
'job' => \App\Jobs\GeneratePdfJob::class,
```

Your custom class should extend the default job:

```
namespace App\Jobs;

use Spatie\LaravelPdf\Jobs\GeneratePdfJob as BaseJob;

class GeneratePdfJob extends BaseJob
{
    public int $tries = 3;

    public int $timeout = 120;

    public int $backoff = 30;
}
```

This lets you set defaults like retry attempts, timeouts, or a default queue for all queued PDF jobs.

Limitations
-----------------------------------------------------------------------------------------

`saveQueued()` cannot be used with `withBrowsershot()`. The closure passed to `withBrowsershot()` may capture objects or state that cannot be reliably serialized for the queue. An exception will be thrown if you try.

Testing
-----------------------------------------------------------------------------

When using `Pdf::fake()`, you can assert that PDFs were queued:

```
use Spatie\LaravelPdf\Facades\Pdf;
use Spatie\LaravelPdf\PdfBuilder;

Pdf::fake();

// ... your code that queues a PDF ...

Pdf::assertQueued('invoice.pdf');

// Or use a callable for more detailed assertions:
Pdf::assertQueued(function (PdfBuilder $pdf, string $path) {
    return $path === 'invoice.pdf' && $pdf->contains('Total');
});

// Assert nothing was queued:
Pdf::assertNotQueued();

// Assert a specific path was not queued:
Pdf::assertNotQueued('other.pdf');
```
