PHPackages                             bkwld/freezer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. bkwld/freezer

ActiveLibrary[Caching](/categories/caching)

bkwld/freezer
=============

Using Laravel, creates cached versions of full pages that can be served directly by Apache

1.4.3(12y ago)106942[5 issues](https://github.com/BKWLD/freezer/issues)MITPHPPHP &gt;=5.3.0

Since Aug 26Pushed 11y ago2 watchersCompare

[ Source](https://github.com/BKWLD/freezer)[ Packagist](https://packagist.org/packages/bkwld/freezer)[ RSS](/packages/bkwld-freezer/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (4)Versions (20)Used By (0)

Freezer
=======

[](#freezer)

Freezer creates full page caches that are **directly** serve-able by Apache. In other words, once a cache is created, PHP doesn't even load to return that cache. Thus, you save the overhead of the whole Laravel stack booting up in addition to eliminating the cost of your application code, database queries, etc.

Freezer does this by creating cache files that can be found directly by Apache through special htaccess rules. Pruning of stale caches is done either by executing of CLI commands (like from cron) or by invoking Freezer's API.

The use-case that Freezer was designed for was small sites that don't see a ton of updates in the CMS. Apache serving a static HTML file can speed up the rendering of pages from 300ms to 3ms.

Installation
------------

[](#installation)

1. Add it to your composer.json (`"bkwld/freezer": "~1.0"`) and do a composer install.
2. Add the service provider to your app.php config file providers: `'Bkwld\Freezer\ServiceProvider',`
3. Add the facade to your app.php config file's aliases: `'Freezer' => 'Bkwld\Freezer\Facade',`
4. Add this to your public/.htaccess file **BEFORE** the Laravel rules involving index.php:

    ```
     # Serve Freezer full page cache files
     RewriteCond %{HTTP_COOKIE} !freezer-skip [NC]
     RewriteCond %{REQUEST_METHOD} GET
     RewriteCond %{DOCUMENT_ROOT}/uploads/freezer/$0\.html -f
     RewriteRule ^.+$ uploads/freezer/$0.html [L]
     RewriteCond %{HTTP_COOKIE} !freezer-skip [NC]
     RewriteCond %{REQUEST_METHOD} GET
     RewriteCond %{DOCUMENT_ROOT}/uploads/freezer/_homepage\.html -f
     RewriteRule ^$ uploads/freezer/_homepage.html [L]

    ```
5. Push config files to your app/config/packages directory for customization with `php artisan config:publish bkwld/freezer`
6. If you are going to use expiration times, setup a worker or cron job to run `php artisan freezer:prune` to delete stale caches. Here is an example for cron that will check for stale caches every minute:

    ```
     * * * * * /path/to/php /path/to/artisan freezer:prune

    ```

Config
------

[](#config)

- `dir` - The directory that you want Freezer to write it's cache files to. It must be writeable and within the document root. In other words, within you /public directory.
- `whitelist` - The a list of regex patterns that match URLs that should be cached. For instance, if you want both /news and /news/15 to be cached, you would have an entry in the array for `news(/\d+)?`. `^` and `\z` are automatically added to the parttern to match against the full url path. If an entry in the array is just a pattern, the cache will never expire. If you use a key-value pair of pattern-lifetime (where lifetime is in minutes), then you can have Freezer automatically expire your catch (as long as you have a Cron setup to auto-prune). For example, `'news*' => 15` will expire all news caches after 15 minutes.
- `blacklist` - The blacklist is processed after the whitelist. Enter patterns that should NOT be cached. For instance, if `news/20` is in the blacklist and `news*` is in the whitelist, then all news articles but the one with id 20 will be full page cached.

**Note**: There is a local/config.php file that comes in the package that disables Freezer locally (for your "local" enviornment) by having an empty whitelist.

API
---

[](#api)

#### `Freezer::clear($pattern, $lifetime)`

[](#freezerclearpattern-lifetime)

Delete cache files that match a pattern or age

- `$pattern` \[string, optional\] A regexp matching the request path that was cached
- `$lifetime` \[number, optional\] Only clear if the cache was created less than this lifetime

#### `Freezer::rebuild($pattern, $lifetime)`

[](#freezerrebuildpattern-lifetime)

Rebuild cache files that match a pattern or age. This works by simulating a GET request to the same route and replacing the cache with the response.

- `$pattern` \[string, optional\] A regexp matching the request path that was cached
- `$lifetime` \[number, optional\] Only clear if the cache was created less than this lifetime

#### `Freezer::debounce($operation, $pattern, $lifetime)`

[](#freezerdebounceoperation-pattern-lifetime)

This is alternate way to invoke `clear` or `rebuild` that puts the call in a queue that gets processed at the end of the Laravel request. The queue is deduped as you add to it. Thus, you can have event listeners call (for example) `Freezer::rebuild()` many times, but only rebuild your cache once.

- `$operation` \[string\] Either 'clear' or 'rebuild'
- `$pattern` \[string, optional\] A regexp matching the request path that was cached
- `$lifetime` \[number, optional\] Only clear if the cache was created less than this lifetime

#### `Freezer::skipNext()`

[](#freezerskipnext)

Adds a cookie to the response that tells Apache not to use the cache to respond to the *next* request. Freezer then deletes this cookie, meaning *only* the subsequent request will be skipped.

Commands
--------

[](#commands)

Note: You will probably need to set explicit app/config/app.php `url` properties for each of your enviornments so that any URLs rendered within your cached pages know what the domain of the site is.

#### `php artisan freezer:clear`

[](#php-artisan-freezerclear)

Delets all cache files

#### `php artisan freezer:prune`

[](#php-artisan-freezerprune)

Deletes only the cache files that have expired based on your config file rules.

Usage
-----

[](#usage)

As mentioned, in the introduction, the primary use-case this packages was designed for is sites that don't receive a ton of updates. In other words, not user-generated-content based sites. One easy was to get up and runnig with Freezer is to put this in your app/start/global.php file:

```
// Delete all Freezer caches when a model changes
// - $m is the model instance that is being acted upon
Event::listen('eloquent.saved*', function($m) { Freezer::debounce('rebuild'); });
Event::listen('eloquent.deleted*', function($m) { Freezer::debounce('rebuild'); });

```

This snippet will dump **all** of the cache whenever you create, update, or delete rows from your database. Combine this with a whitelist on everything (`*`) except your admin directory (blacklist `admin*`) and you have a system where all your front-facing pages will get cached but will still immediately see any changes made in your admin. You don't even need to setup a cron job with this approach.

Another handy thing to have in your app/start/global.php is this:

```
// Skip caching the next page after any non-GET.  For instance, don't cache
// the page that is shown after submitting a form
if (Request::getMethod() != 'GET') Freezer::skipNext();

```

This will skip caching or serving all requests that follow a POST, PUT, or DELETE.

Remember to clear your Freezer cache on the server (`php artisan freezer:clear`) when deploying new code.

###  Health Score

31

—

LowBetter than 66% of packages

Maintenance10

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 98% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~10 days

Total

19

Last Release

4498d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/77567?v=4)[Robert Reinhard](/maintainers/weotch)[@weotch](https://github.com/weotch)

---

Top Contributors

[![weotch](https://avatars.githubusercontent.com/u/77567?v=4)](https://github.com/weotch "weotch (48 commits)")[![sdaves](https://avatars.githubusercontent.com/u/498681?v=4)](https://github.com/sdaves "sdaves (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/bkwld-freezer/health.svg)

```
[![Health](https://phpackages.com/badges/bkwld-freezer/health.svg)](https://phpackages.com/packages/bkwld-freezer)
```

###  Alternatives

[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.7M64](/packages/spatie-laravel-responsecache)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k55.1k1](/packages/mike-bronner-laravel-model-caching)[illuminate/auth

The Illuminate Auth package.

9327.9M1.2k](/packages/illuminate-auth)[spatie/laravel-export

Create a static site bundle from a Laravel app

672139.5k6](/packages/spatie-laravel-export)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45344.0k1](/packages/pressbooks-pressbooks)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
