{"id":19756436,"url":"https://github.com/backstagephp/laravel-permanent-cache","last_synced_at":"2025-08-22T12:32:46.738Z","repository":{"id":215263570,"uuid":"705171389","full_name":"backstagephp/laravel-permanent-cache","owner":"backstagephp","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-26T20:46:50.000Z","size":215,"stargazers_count":6,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-15T22:04:15.099Z","etag":null,"topics":["backstage","cache","laravel","permanent-cache","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/backstagephp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"backstagephp"}},"created_at":"2023-10-15T08:43:43.000Z","updated_at":"2025-02-26T20:47:52.000Z","dependencies_parsed_at":"2024-01-24T12:01:26.182Z","dependency_job_id":"81df0fbb-9ad4-4a3b-bdc7-29d0b8ed6746","html_url":"https://github.com/backstagephp/laravel-permanent-cache","commit_stats":null,"previous_names":["vormkracht10/laravel-permanent-cache","backstagephp/laravel-permanent-cache"],"tags_count":20,"template":false,"template_full_name":"vormkracht10/laravel-package-template","purl":"pkg:github/backstagephp/laravel-permanent-cache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/backstagephp%2Flaravel-permanent-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/backstagephp%2Flaravel-permanent-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/backstagephp%2Flaravel-permanent-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/backstagephp%2Flaravel-permanent-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/backstagephp","download_url":"https://codeload.github.com/backstagephp/laravel-permanent-cache/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/backstagephp%2Flaravel-permanent-cache/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271637765,"owners_count":24794536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backstage","cache","laravel","permanent-cache","php"],"created_at":"2024-11-12T03:15:57.487Z","updated_at":"2025-08-22T12:32:46.646Z","avatar_url":"https://github.com/backstagephp.png","language":"PHP","funding_links":["https://github.com/sponsors/backstagephp"],"categories":[],"sub_categories":[],"readme":"# Laravel Permanent Cache\n\n[![Total Downloads](https://img.shields.io/packagist/dt/backstage/laravel-permanent-cache.svg?style=flat-square)](https://packagist.org/packages/backstage/laravel-permanent-cache)\n[![Tests](https://github.com/backstagephp/laravel-permanent-cache/actions/workflows/pest.yml/badge.svg?branch=main)](https://github.com/backstagephp/laravel-permanent-cache/actions/workflows/run-tests.yml)\n[![PHPStan](https://github.com/backstagephp/laravel-permanent-cache/actions/workflows/phpstan.yml/badge.svg?branch=main)](https://github.com/backstagephp/laravel-permanent-cache/actions/workflows/phpstan.yml)\n![GitHub release (latest by date)](https://img.shields.io/github/v/release/backstagephp/laravel-permanent-cache)\n![Packagist PHP Version Support](https://img.shields.io/packagist/php-v/backstage/laravel-permanent-cache)\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/backstage/laravel-permanent-cache.svg?style=flat-square)](https://packagist.org/packages/backstage/laravel-permanent-cache)\n\nThis package aims to provide functionality of using a *permanent* cache for tasks using heavy Eloquent models, database queries or other long running tasks in your Laravel app. The permanent cache updates itself in the background using a scheduled task or by listening to an event so no users are harmed waiting on a given request.\n\nIts use case is primarily to be used for heavy tasks that should return complex data or HTML for the front-end that does not need to be realtime but still regularly updated. Think about external API calls that take a few seconds to process or other 1+ second tasks.\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require backstage/laravel-permanent-cache\n```\n\nOptionally, publish config files to change the default config:\n\n```bash\nphp artisan vendor:publish --provider=\"Backstage\\PermanentCache\\Laravel\\PermanentCacheServiceProvider\"\n```\n\nThe default config options:\n\n```php\n\u003c?php\n\nreturn [\n    // Default cache driver to use for permanent cache\n    'driver' =\u003e env('PERMANENT_CACHE_DRIVER', 'file'),\n\n    // Option for cached components to add markers around output\n    'components' =\u003e [\n        // Add markers around the rendered value of Cached Components,\n        // this helps to identify the cached value in the rendered HTML.\n\n        // Which is useful for debugging and testing, but also for updating\n        // the cached value inside another cache when using nested caches\n        'markers' =\u003e [\n            'enabled' =\u003e env('PERMANENT_CACHE_MARKERS_ENABLED', true),\n            'hash' =\u003e env('PERMANENT_CACHE_MARKERS_HASH', env('APP_ENV') === 'production'),\n        ],\n    ],\n];\n```\n\n# Usage\n\nAll caches you create must be registered to the `PermanentCache::caches` facade. \nWe recommend putting this in the `boot` method of your `AppServiceProvider`.\n\nYou can register caches in multiple ways:\n\n```php\nuse Backstage\\PermanentCache\\Laravel\\Facades\\PermanentCache;\n\n# When you don't need parameters per class, you can use direct parameters or an array:\n\n# Without an array\nPermanentCache::caches(\n    LongRunningTask::class,\n    LongerRunningTask::class,\n);\n\n# Passing an array\n$caches = [\n    LongRunningTask::class,\n    LongerRunningTask::class,\n];\n\nPermanentCache::caches($caches);\n\n# Specifying parameters per class\nPermanentCache::caches([\n    LongRunningTask::class =\u003e ['type' =\u003e 'long'],\n    LongerRunningTask::class =\u003e ['type' =\u003e 'longer'],\n]);\n\n# As a multi-dimensional array when you need to use the same class multiple times, but with different parameters\nPermanentCache::caches(\n    [LongRunningTask::class =\u003e ['type' =\u003e 'long']],\n    [LongRunningTask::class =\u003e ['type' =\u003e 'longer']],\n);\n```\n\n## Definition of a Permanent Cache\n\nA Permanent Cache could be a task that runs longer than you'd want your users to wait for. \nThat's why you need to run it in the background, updating periodically using the scheduler\nor when events happen and/or using help of Laravel's queue system.\n\nYou can define the cache store and key using a `$store` property on the class, following \nthe definition: `cache-driver:key`, for example: `redis:a-unique-cache-key`:\n\n```php\nuse Backstage\\PermanentCache\\Laravel\\Cached;\n\nclass LongRunningTask extends Cached\n{\n    protected $store = 'redis:a-unique-cache-key';\n\n    public function run(): string\n    {\n        return \"I'm executing a long running task!\";\n    }\n}\n```\n\n## Caches can listen for events\n\nIf you only want to listen for a single event you can type hint the event in the `run` method:\n\n```php\nuse Backstage\\PermanentCache\\Laravel\\Cached;\n\nclass LongRunningTaskListeningForEvents extends Cached\n{\n    protected $store = 'redis:unique-cache-key';\n\n    public function run(TestEvent $event): string\n    {\n        return \"I'm executing because of {$event-\u003ename}!\";\n    }\n}\n```\n\n### Listening for multiple events\n\nPermanent Caches can be updated by listening to *multiple* events using an array on the `$events` property:\n\n```php\nuse Backstage\\PermanentCache\\Laravel\\Cached;\n\nclass LongRunningTaskListeningForEvents extends Cached\n{\n    protected $store = 'redis:unique-cache-key';\n\n    protected $events = [\n        TestEvent::class,\n        OtherEvent::class,\n    ];\n    \n    /** @param TestEvent|OtherEvent $event */\n    public function run($event): string\n    {\n        return \"I'm executing because of {$event-\u003ename}!\";\n    }\n}\n```\n\n## Caches can be updated periodically using the scheduler\n\nPermanent Caches can be updated using the scheduler (while also listening for events) by adding a `schedule` method or a `$expression` property with a cron string.\n\nNote that if you decide to listen to events *and* schedule your cache, you shouldn't try to\naccept an `$event` parameter in the `run` method, because when the schedule runs, this won't be given to you.\n\n```php\nuse Backstage\\PermanentCache\\Laravel\\Cached;\nuse Backstage\\PermanentCache\\Laravel\\Scheduled;\n\nclass LongRunningTaskExecutedPeriodicallyOrWhenAnEventHappens extends Cached implements Scheduled\n{\n    protected $store = 'redis:unique-cache-key';\n\n    protected $events = [\n        TestEvent::class,\n    ];\n\n    // Use cron expression\n    protected $expression = '* * * * *'; // run every minute\n\n    public function run(): string\n    {\n        return \"I'm executing because of {$event-\u003ename} or a scheduled run!\";\n    }\n\n    // Or use the `schedule` method using a callback\n    public static function schedule($callback)\n    {\n        return $callback-\u003eeveryHour();\n    }\n}\n```\n\n## Caches can be updated by dispatching on the queue\n\nPermanent Caches can be updated using a dispatch to the queue by implementing Laravel's `ShouldQueue` interface and (optionally) specifying a queue:\n\n```php\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Backstage\\PermanentCache\\Laravel\\Cached;\nuse Backstage\\PermanentCache\\Laravel\\Scheduled;\n\nclass LongRunningTaskExecutedPeriodicallyOrWhenAnEventHappensDispatchedOnTheQueue extends Cached implements ShouldQueue\n{\n    protected $store = 'redis:unique-cache-key';\n\n    public $queue = 'execute-on-this-queue';\n\n    public function run(TestEvent $event): string\n    {\n        return \"I'm dispatching for execution on the queue because of {$event-\u003ename}!\";\n    }\n}\n```\n\n## Feature: Cached Blade Components\n\nOne super handy feature are \"Cached Components\", these are Blade Components that could contain a longer running task on which you don't want your users to wait for completing. So you execute the Blade component when needed in the background,\nusing the scheduler, or queue, while optionally listening for events to happen that will cause the permanent cache to update.\n\n```php\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Backstage\\PermanentCache\\Laravel\\CachedComponent;\nuse Backstage\\PermanentCache\\Laravel\\Scheduled;\n\nclass HeavyComponent extends CachedComponent implements Scheduled, ShouldQueue\n{\n    protected $store = 'redis:unique-cache-key';\n\n    protected $events = [\n        TestEvent::class,\n    ];\n\n    public function render()\n    {\n        return view('components.heavy-component');\n    }\n\n    public static function schedule($callback)\n    {\n        return $callback-\u003eeveryHour();\n    }\n}\n```\n\nWhen loading your Blade component, it will always use cache instead of executing a long during task:\n\n```blade\n\u003cx-long-during-task /\u003e\n```\n\n## Manually updating permanent caches\n\nManually updating a permanent cache is very simple. Just use the static `update` method. \nThis will automatically run or queue the execution of the task:\n\n```php\nLongTaskInPermanentCache::update(['parameter' =\u003e 'value']);\n```\n\nOr you can update all caches at once:\n\n```php\nuse Backstage\\PermanentCache\\Laravel\\Facades\\PermanentCache;\n\nPermanentCache::update();\n```\n\n## Events when updating Permanent Caches\n\nThese events get dispatched when a Permanent Cache gets updated:\n\n```php\n# Before updating the cache\nuse Backstage\\PermanentCache\\Laravel\\Events\\PermanentCacheUpdating;\n\n# After the cache has been updated\nuse Backstage\\PermanentCache\\Laravel\\Events\\PermanentCacheUpdated;\n```\n\n## Console commands\n\nThis package contains Artisan commands to optimize DX when implementing Permanent Cache:\n\n```php\n# Update all caches that match namespace using the optional filter\nphp artisan permanent-cache:update --filter=\n\n# Show status overview of all registered caches including cached status, cache size, last updated at and scheduled update frequency\nphp artisan permanent-cache:status --parameters --filter=\n```\n\n##### [Read more on Jobs \u0026 Queues](https://laravel.com/docs/queues)\n\n## Credits\n\n-   [Mark van Eijk](https://github.com/markvaneijk)\n-   [David den Haan](https://github.com/david-d-h)\n-   [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see the [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbackstagephp%2Flaravel-permanent-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbackstagephp%2Flaravel-permanent-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbackstagephp%2Flaravel-permanent-cache/lists"}