Caching PDFs | laravel-pdf | Spatie

 SPATIE

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

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-pdf](https://spatie.be/docs/laravel-pdf/v2)  Advanced-usage  Caching PDFs

 Version   v2   v1

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

  Caching PDFs
- [ 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)
- [ Attaching PDFs to mails ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/attaching-pdfs-to-mails)
- [ 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)
- [ Protecting PDFs with a password ](https://spatie.be/docs/laravel-pdf/v2/basic-usage/protecting-pdfs-with-a-password)

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 Chrome driver ](https://spatie.be/docs/laravel-pdf/v2/drivers/using-the-chrome-driver)
- [ 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)
- [ Waiting for readiness ](https://spatie.be/docs/laravel-pdf/v2/advanced-usage/waiting-for-readiness)
- [ Caching PDFs ](https://spatie.be/docs/laravel-pdf/v2/advanced-usage/caching-pdfs)

 Caching PDFs
============

###  On this page

1. [ Caching a render ](#content-caching-a-render)
2. [ Setting a lifetime ](#content-setting-a-lifetime)
3. [ Caching every PDF by default ](#content-caching-every-pdf-by-default)
4. [ How the cache key is determined ](#content-how-the-cache-key-is-determined)
5. [ Configuring the cache ](#content-configuring-the-cache)
6. [ Customizing the caching behaviour ](#content-customizing-the-caching-behaviour)
7. [ Caching and ](#content-caching-and-withbrowsershot)
8. [ Caching and queued generation ](#content-caching-and-queued-generation)

Rendering a PDF with a Chromium based driver is relatively expensive. When the same document is generated repeatedly, you can cache the rendered result so identical renders are served from the cache instead of being generated again.

Caching a render
--------------------------------------------------------------------------------------------------------

Call `cache()` on the builder. The first render is generated and stored. Every subsequent render with identical input is served from the cache.

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

Pdf::view('pdf.invoice', ['invoice' => $invoice])
    ->cache()
    ->download('invoice.pdf');
```

Caching applies to every output method, including `save()`, `download()`, `base64()`, returning the PDF as a response, and attaching it to a mail.

Setting a lifetime
--------------------------------------------------------------------------------------------------------------

By default a cache entry lives for one day. Pass a lifetime to use a different duration. It accepts a number of seconds, a `DateInterval`, or a `DateTimeInterface`.

```
Pdf::view('pdf.invoice', ['invoice' => $invoice])
    ->cache(3600) // seconds
    ->save('invoice.pdf');
```

A Carbon instance (or any `DateTimeInterface`) works too, expiring the entry at that moment.

```
Pdf::view('pdf.invoice', ['invoice' => $invoice])
    ->cache(now()->endOfDay())
    ->save('invoice.pdf');
```

On Laravel versions that ship the duration helpers (`minutes`, `hours`, `days`), you can use those for an even more expressive lifetime.

```
use function Illuminate\Support\hours;

Pdf::view('pdf.invoice', ['invoice' => $invoice])
    ->cache(hours(2))
    ->save('invoice.pdf');
```

Caching every PDF by default
--------------------------------------------------------------------------------------------------------------------------------------------

If you want every PDF to be cached without calling `cache()` each time, turn on automatic caching in the config file (or set `LARAVEL_PDF_CACHE_AUTOMATIC=true` in your `.env`).

```
'cache' => [
    'automatic' => env('LARAVEL_PDF_CACHE_AUTOMATIC', true),
],
```

With caching enabled, calling `cache()` still works to override the lifetime or key for a specific PDF. To skip the cache for a single PDF, call `dontCache()`.

```
Pdf::view('pdf.receipt', ['receipt' => $receipt])
    ->dontCache()
    ->download('receipt.pdf');
```

How the cache key is determined
-----------------------------------------------------------------------------------------------------------------------------------------------------

By default the cache key is derived from everything that influences the output: the rendered HTML, the header and footer, all formatting options, the metadata, and the encryption settings. Two renders that differ in any of these get separate cache entries, so you never accidentally serve the wrong PDF.

If you want full control over the key, pass your own as the second argument. This is useful when you can describe a render with a stable identifier, such as an invoice id.

```
Pdf::view('pdf.invoice', ['invoice' => $invoice])
    ->cache(key: "invoice-{$invoice->id}")
    ->save('invoice.pdf');
```

Configuring the cache
-----------------------------------------------------------------------------------------------------------------------

The caching behaviour is configured in the `cache` section of the `laravel-pdf` config file.

```
'cache' => [
    'class' => Spatie\LaravelPdf\Caching\DefaultPdfCache::class,
    'automatic' => env('LARAVEL_PDF_CACHE_AUTOMATIC', false),
    'store' => env('LARAVEL_PDF_CACHE_STORE'),
    'prefix' => 'laravel-pdf',
    'ttl' => env('LARAVEL_PDF_CACHE_TTL', 60 * 60 * 24),
],
```

- `automatic`: when `true`, every PDF is cached without calling `cache()`. Defaults to `false`.
- `store`: the cache store to use. Leave it `null` to use your application's default store.
- `prefix`: the prefix prepended to every cache key.
- `ttl`: the default lifetime in seconds. Defaults to one day. Set it to `null` to cache forever.

Customizing the caching behaviour
-----------------------------------------------------------------------------------------------------------------------------------------------------------

If you need to change how PDFs are keyed, stored, or expired, you can replace the entire caching implementation. Create a class that implements the `Spatie\LaravelPdf\Caching\PdfCache` contract.

```
namespace App\Support;

use Closure;
use Spatie\LaravelPdf\Caching\PdfCache;

class MyPdfCache implements PdfCache
{
    public function remember(string $fingerprint, ?string $key, ?int $ttl, Closure $generate): string
    {
        // Return the cached PDF content, generating and storing it when needed.
    }
}
```

Register it in the `cache.class` key of the config file.

```
'cache' => [
    'class' => App\Support\MyPdfCache::class,
],
```

Caching and `withBrowsershot()`
---------------------------------------------------------------------------------------------------------------------------------------------

A closure passed to `withBrowsershot()` can change the output, but it cannot be added to the cache key. Caching a PDF that is customized this way throws an exception unless you pass an explicit key, which makes you responsible for keeping it unique.

```
Pdf::view('pdf.invoice', ['invoice' => $invoice])
    ->withBrowsershot(fn ($browsershot) => $browsershot->setRemoteInstance('127.0.0.1', 9222))
    ->cache(key: "invoice-{$invoice->id}")
    ->save('invoice.pdf');
```

Caching and queued generation
-----------------------------------------------------------------------------------------------------------------------------------------------

Caching applies to PDFs generated synchronously. PDFs generated with [queued generation](/docs/laravel-pdf/v2/basic-usage/queued-pdf-generation) are not cached.

 A good
match?
-------------

### What we do best

- All things Laravel
- Custom frontend components
- Building APIs
- AI-powered features
- Simplifying things
- Clean solutions
- Integrating services

### Not our cup of tea

- WordPress themes
- Cutting corners
- Free mockups to win a job
- "Just execute the briefing"

 In short: we'd like to be a **substantial part** of your project.

 [ Get in touch via email ](mailto:info@spatie.be?subject=A%20good%20match%21&body=Tell%20us%20as%20much%20as%20you%20can%20about%0A-%20your%20online%20project%0A-%20your%20planning%0A-%20your%20budget%0A-%20%E2%80%A6%0A%0AAnything%20that%20helps%20us%20to%20start%20straightforward%21)
