PHPackages                             padosoft/laravel-super-cache - 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. padosoft/laravel-super-cache

ActiveLibrary[Caching](/categories/caching)

padosoft/laravel-super-cache
============================

A Laravel package for advanced caching with tags and namespaces in Redis.

v2.2.0(2mo ago)29.1k↓74.4%2[1 PRs](https://github.com/padosoft/laravel-super-cache/pulls)MITPHPPHP ^8.0CI failing

Since Oct 4Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/padosoft/laravel-super-cache)[ Packagist](https://packagist.org/packages/padosoft/laravel-super-cache)[ Docs](https://github.com/padosoft/laravel-super-cache)[ RSS](/packages/padosoft-laravel-super-cache/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (10)Dependencies (34)Versions (46)Used By (0)

Laravel Super Cache
===================

[](#laravel-super-cache)

[![Laravel Super Cache](./resources/images/laravel-super-cache-logo.webp)](./resources/images/laravel-super-cache-logo.webp)

A powerful caching solution for Laravel that uses Redis with Lua scripting, batch processing, and optimized tag management to handle high volumes of keys efficiently.

[![Latest Version on Packagist](https://camo.githubusercontent.com/53a97e42ee9b7b3a5136452ea8b36271248bc0116ed350bce0bbc97e5296df9c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7061646f736f66742f6c61726176656c2d73757065722d63616368652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/padosoft/laravel-super-cache)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![CircleCI](https://camo.githubusercontent.com/2281e7e5542d05168f8e65d5b9fee18f84a9891693bee46f09fa2e68a8598220/68747470733a2f2f636972636c6563692e636f6d2f67682f7061646f736f66742f6c61726176656c2d73757065722d63616368652e7376673f7374796c653d736869656c64)](https://circleci.com/gh/padosoft/laravel-super-cache)[![Quality Score](https://camo.githubusercontent.com/b3dcda05376a7a286841553fab40b5d6e4f1b202d4206b7f32a20144cc61b5d0/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f7061646f736f66742f6c61726176656c2d73757065722d63616368652e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/padosoft/laravel-super-cache)[![Total Downloads](https://camo.githubusercontent.com/58c90ad9b12f22a5c5e83f09ced717021437ae7f1d9e8790cfbeed715bc8198f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7061646f736f66742f6c61726176656c2d73757065722d63616368652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/padosoft/laravel-super-cache)

Table of Contents
-----------------

[](#table-of-contents)

- [Purpose](#purpose)
- [Why Use This Package?](#why-use-this-package)
- [Features](#features)
- [Requires](#requires)
- [Installation and Configuration](#installation-and-configuration)
    - [Activating the Listener for Expiry Notifications](#activating-the-listener-for-expiry-notifications)
    - [Enabling Redis Expiry Notifications (required for listener)](#enabling-redis-expiry-notifications-required-for-listener)
    - [Scheduled Command for Orphaned Key Cleanup (optional but recommended)](#scheduled-command-for-orphaned-key-cleanup-optional-but-recommended)
    - [Additional Artisan Commands](#additional-artisan-commands)
- [Usage Examples](#usage-examples)
- [Architecture Overview](#architecture-overview)
- [Design Decisions and Performance](#design-decisions-and-performance)
    - [Key and Tag Organization](#key-and-tag-organization)
    - [Sharding for Efficient Tag Management](#sharding-for-efficient-tag-management)
    - [Locks for Concurrency Control](#locks-for-concurrency-control)
    - [Handling Expire Correctly with TTLs](#handling-expire-correctly-with-ttls)
    - [Namespace Suffix for Parallel Processing](#namespace-suffix-for-parallel-processing)
    - [Scheduled Command for Orphaned Key Cleanup](#scheduled-command-for-orphaned-key-cleanup)

Purpose
-------

[](#purpose)

`laravel-super-cache` is designed to provide a high-performance, reliable, and scalable caching solution for Laravel applications that require efficient tag-based cache invalidation. By leveraging Redis's native capabilities and optimizing the way tags are managed, this package addresses limitations in Laravel's built-in cache tag system, making it suitable for large-scale enterprise applications.

Why Use This Package?
---------------------

[](#why-use-this-package)

Laravel's native caching mechanism has an implementation for tag-based cache management; however, it faces limitations, especially when dealing with high volumes of cache keys and frequent invalidations. Some of the issues include:

1. **Inconsistency with Tag Invalidation**: Laravel uses a versioned tag strategy, which can lead to keys not being properly invalidated when associated tags change, particularly in highly concurrent environments.
2. **Performance Overhead**: The default implementation in Laravel relies on a "soft invalidate" mechanism that increments tag versions instead of directly removing keys, which can lead to slower cache operations and memory growth (memory leaks).
3. **Scalability Issues**: The handling of large volumes of tags and keys is not optimized for performance, making it difficult to maintain consistency and speed in enterprise-level applications.

`laravel-super-cache` addresses these limitations by providing an efficient, high-performance caching layer optimized for Redis, leveraging Lua scripting, and batch processing techniques.

Features
--------

[](#features)

- **Architecture for High Volume**: Designed to handle thousands of cache keys with rapid creation and deletion, without performance degradation.
- **Enterprise-Level Performance**: Uses Redis's native capabilities and optimizes cache storage and retrieval for high-speed operations.
- **Use of Lua Scripting for Efficiency**: Employs Lua scripts for atomic operations, reducing network round-trips and improving consistency.
- **Batch Processing and Pipelining**: Processes cache operations in batches, reducing overhead and maximizing throughput.
- **Parallel Processing with Namespaces**: Enables parallel processing of expiry notifications by using namespace suffixing and configurable listeners.

Requires
--------

[](#requires)

- php: &gt;=8.0
- laravel/framework: ^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^9.0|^10.0|^11.0|^12.0|^13.0
- predis/predis: ^2.0
- ext-redis

Installation and Configuration
------------------------------

[](#installation-and-configuration)

To install `laravel-super-cache`, use Composer:

```
composer require padosoft/laravel-super-cache
```

The service provider and the `SuperCache` facade alias are auto-discovered by Laravel (see `extra.laravel` in `composer.json`), so no manual registration in `config/app.php` is required.

Publish the configuration file:

```
php artisan vendor:publish --provider="Padosoft\SuperCache\SuperCacheServiceProvider"
```

The configuration file (`config/supercache.php`) exposes the following keys (each backed by an env variable):

- `prefix` (`SUPERCACHE_PREFIX`, default `supercache:`): prefix applied to all cache keys to avoid conflicts on a shared Redis instance.
- `connection` (`SUPERCACHE_CONNECTION`, default `default`): Redis connection name defined in `config/database.php`.
- `num_shards` (`SUPERCACHE_NUM_SHARDS`, default `256`): number of shards used to spread keys across per-tag sets.
- `use_namespace` (`SUPERCACHE_USE_NAMESPACE`, default `false`): enables namespace suffixing on keys so that multiple listener processes can work in parallel.
- `num_namespace` (`SUPERCACHE_NUM_NAMESPACE`, default `16`): number of namespaces available when `use_namespace` is enabled.
- `batch_size` (`SUPERCACHE_BATCH_SIZE`, default `100`): maximum number of keys accumulated by the listener before a batch is flushed.
- `time_threshold` (`SUPERCACHE_TIME_THRESHHOLD`, default `1`): maximum time in seconds before the listener flushes a batch even if `batch_size` has not been reached.
- `advancedMode` (`SUPERCACHE_ADVANCED_MODE`, default `0`): when set to `1`, also stores the reverse `key → tags` set (`tags:`), enabling deeper cleanup at the cost of extra writes.
- `log_to_elastic_function` (`SUPERCACHE_LOG_TO_ELASTIC_FUNCTION`): optional callable used to forward internal operations (e.g. `forget`) to an external logging backend.

### Activating the Listener for Expiry Notifications

[](#activating-the-listener-for-expiry-notifications)

The listener is responsible for handling expired cache keys and cleaning up associated tags. To activate it, run it under a process supervisor (e.g. `supervisor`):

```
[program:supercache_listener]
command=php artisan supercache:listener --namespace_id=%(process_num)s
numprocs=5
```

The full signature is:

```
php artisan supercache:listener
    [--connection_name=]
    [--namespace_id=]
    [--checkEvent=1]
    [--host=]
    [--port=]

```

When `supercache.use_namespace` is `true`, run one listener per `--namespace_id` (0 .. `num_namespace - 1`) so each process handles only its own slice of expiry notifications, enabling parallel processing.

### Enabling Redis Expiry Notifications (required for listener)

[](#enabling-redis-expiry-notifications-required-for-listener)

To enable the expiry notifications required by `laravel-super-cache`, you need to configure Redis (or AWS ElastiCache) to send `EXPIRED` events. Here's how you can do it:

#### For a Standard Redis Instance

[](#for-a-standard-redis-instance)

1. **Edit Redis Configuration**: Open the `redis.conf` file and set the `notify-keyspace-events` parameter to enable expiry notifications.

    ```
    notify-keyspace-events Ex
    ```

    This configuration enables notifications for key expirations (Ex), which is required for the listener to function correctly.
2. **Using Redis CLI**: Alternatively, you can use the Redis CLI to set the configuration without editing the file directly.

    ```
    redis-cli config set notify-keyspace-events Ex
    ```

This command will apply the changes immediately without needing a Redis restart.

#### For AWS ElastiCache Redis

[](#for-aws-elasticache-redis)

If you are using Redis on AWS ElastiCache, follow these steps to enable expiry notifications:

1. **Access the AWS ElastiCache Console:**

    - Go to the ElastiCache dashboard on your AWS account.
2. **Locate Your Redis Cluster:**

    - Find your cluster or replication group that you want to configure.
3. **Modify the Parameter Group:**

    - Go to the **Parameter Groups** section.
    - Find the parameter group associated with your cluster, or create a new one.
    - Search for the `notify-keyspace-events` parameter and set its value to `Ex`.
    - Save changes to the parameter group.
4. **Attach the Parameter Group to Your Redis Cluster:**

    - Attach the modified parameter group to your Redis cluster.
    - A **cluster reboot** may be required for the changes to take effect.

After configuring the `notify-keyspace-events` parameter, Redis will publish `EXPIRED` events when keys expire, allowing the `laravel-super-cache` listener to process these events correctly.

Make sure PHP is configured with the following setting, otherwise the listener command will exit after 60 seconds because the Redis connection gets interrupted:

```
default_socket_timeout = -1

```

### Scheduled Command for Orphaned Key Cleanup (optional but recommended)

[](#scheduled-command-for-orphaned-key-cleanup-optional-but-recommended)

Optionally but recommended, a scheduled command can be configured to periodically clean up any orphaned keys or sets left due to unexpected interruptions or errors. This adds an additional safety net to maintain consistency across cache keys and tags.

```
php artisan supercache:clean-orphans [--connection_name=]
```

This can be scheduled using Laravel's scheduler to run at appropriate intervals, ensuring your cache remains clean and optimized.

### Additional Artisan Commands

[](#additional-artisan-commands)

- `supercache:get-tags {key}`: prints all tags currently associated with the given cache key (useful for debugging).
- `supercache:get-cluster-nodes [--connection_name=]`: lists the nodes of the configured Redis cluster, used internally by the listener and the orphan cleaner when running against a cluster.

Usage Examples
--------------

[](#usage-examples)

Below are examples of using the `SuperCacheManager` through its facade. The facade class is `Padosoft\SuperCache\Facades\SuperCacheFacade` and is auto-aliased to `SuperCache`:

```
use SuperCache; // alias registered by the package

// Store an item in cache (optional TTL in seconds, optional Redis connection name)
SuperCache::put('user:1', $user, 3600);

// Store an item in cache with tags
// Extra optional params: $ttl, $connection_name, $serialize (default true),
// $disableCompression (default false, useful on Redis clusters using OPT_COMPRESSION)
SuperCache::putWithTags('product:1', $product, ['products', 'featured'], 3600);

// Remember: read-through cache with tags
$product = SuperCache::rememberWithTags('product:1', ['products'], function () {
    return Product::find(1);
}, 3600);

// Retrieve an item from cache
$product = SuperCache::get('product:1');

// Check if a key exists
$exists = SuperCache::has('user:1');

// Get the TTL of a key (in seconds)
$ttl = SuperCache::getTTLKey('user:1');

// Increment / decrement counters
SuperCache::increment('views:product:1');
SuperCache::decrement('stock:product:1', 5);

// Remove a single key (and, in advanced mode, its tag references)
SuperCache::forget('user:1');

// Invalidate every key associated with one or more tags
SuperCache::flushByTags(['products', 'featured']);

// Introspection helpers
$tagsOfKey = SuperCache::getTagsOfKey('product:1');
$keysOfTag = SuperCache::getKeysOfTag('products');

// Get all keys matching one or more patterns
$keys = SuperCache::getKeys(['product:*']);

// Acquire / release a short-lived optimistic lock
if (SuperCache::lock('job:import', null, 10)) {
    try {
        // critical section
    } finally {
        SuperCache::unLock('job:import');
    }
}

// Flush the whole SuperCache keyspace on a given connection
SuperCache::flush();
```

Every write/read method accepts an optional `?string $connection_name` as its last argument, so you can target a specific Redis connection defined in `config/database.php`. For the full signature of every method, see `src/SuperCacheManager.php`.

Architecture Overview
---------------------

[](#architecture-overview)

[![the-architecture.webp](resources%2Fimages%2Fthe-architecture.webp)](resources%2Fimages%2Fthe-architecture.webp)

Design Decisions and Performance
--------------------------------

[](#design-decisions-and-performance)

### Key and Tag Organization

[](#key-and-tag-organization)

[![add key.webp](resources%2Fimages%2Fadd%20key.webp)](resources%2Fimages%2Fadd%20key.webp)[![remove key.webp](resources%2Fimages%2Fremove%20key.webp)](resources%2Fimages%2Fremove%20key.webp)Each cache key is stored with an associated set of tags. These tags allow efficient invalidation when certain categories of keys need to be cleared. The structure ensures that any cache invalidation affects only the necessary keys without touching unrelated data.

Tag-Based Cache Architecture
----------------------------

[](#tag-based-cache-architecture)

To efficiently handle cache keys and their associated tags, `laravel-super-cache` employs a well-defined architecture using Redis data structures. This ensures high performance for lookups, tag invalidations, and efficient management of keys. Below is a breakdown of how the package manages and stores these data structures in Redis.

### 3 Main Structures in Redis

[](#3-main-structures-in-redis)

1. **Key-Value Storage**:

    - Each cache entry is stored as a key-value pair in Redis.
    - **Naming Convention**: The cache key is prefixed for the package (e.g., `supercache:key:`), ensuring no conflicts with other Redis data.
2. **Set for Each Tag (Tag-Key Sets)**:

    - For every tag associated with a key, a Redis set is created to hold all the keys associated with that tag.
    - **Naming Convention**: Each set is named with a pattern like `supercache:tag::shard:`, where `` is the tag name and `` is determined by the sharding algorithm.
    - These sets allow quick retrieval of all keys associated with a tag, facilitating efficient cache invalidation by tag.
3. **Set for Each Key (Key-Tag Sets) — advanced mode only**:

    - When `supercache.advancedMode` is enabled (`SUPERCACHE_ADVANCED_MODE=1`), each cache key also gets a companion set that holds all of its tags.
    - **Naming Convention**: the set is named `tags:` (e.g. `supercache:tags:supercache:key:product:123`).
    - This structure allows quick identification of which tags are associated with a key, enabling deeper clean-up when a key is deleted via `forget`. In the default mode this reverse set is not written, so tag clean-up relies exclusively on the Redis expiry-notification listener.

### Sharding for Efficient Tag Management

[](#sharding-for-efficient-tag-management)

To optimize performance when dealing with potentially large sets of keys associated with a single tag, `laravel-super-cache` employs a **sharding strategy**:

- **Why Sharding?**: A single tag might be associated with a large number of keys. If all keys for a tag were stored in a single set, this could degrade performance. Sharding splits these keys across multiple smaller sets, distributing the load.
- **How Sharding Works**: When a key is added to a tag, a fast hash function (e.g., `crc32`) is used to compute a shard index. The key is then stored in the appropriate shard for that tag.
    - **Naming Convention for Sharded Sets**: Each set for a tag is named as `supercache:tag::shard:`.
    - The number of shards is configurable through the `SUPERCACHE_NUM_SHARDS` setting, allowing you to balance between performance and memory usage.

### Example: Creating a Cache Key with Tags

[](#example-creating-a-cache-key-with-tags)

When you create a cache key with associated tags, here's what happens:

1. **Key-Value Pair**: A key-value pair is stored in Redis, prefixed as `supercache:key:`.
2. **Tag-Key Sets**: For each tag associated with the key:
    - A shard is determined using a hash function.
    - The key is added to the corresponding sharded set for the tag, named as `supercache:tag::shard:`.
3. **Key-Tag Set**: A set is created to associate the key with its tags, named as `supercache:tags:`.

This structure allows efficient lookup, tagging, and invalidation of cache entries.

#### Example

[](#example)

Suppose you cache a key `product:123` with tags `electronics` and `featured`. The following structures would be created in Redis:

- **Key-Value Pair**:

    - `supercache:key:product:123` -&gt; ``
- **Tag-Key Sets**:

    - Assuming `SUPERCACHE_NUM_SHARDS` is set to 256, and `product:123` hashes to shard `42` for `electronics` and shard `85` for `featured`:
        - `supercache:tag:electronics:shard:42` -&gt; contains `supercache:key:product:123`
        - `supercache:tag:featured:shard:85` -&gt; contains `supercache:key:product:123`
- **Key-Tag Set**:

    - `supercache:tags:product:123` -&gt; contains `electronics`, `featured`

### Benefits of This Architecture

[](#benefits-of-this-architecture)

- **Efficient Lookups and Invalidation**: Using sets for both tags and keys enables quick lookups and invalidation of cache entries when necessary.
- **Scalable Performance**: The sharding strategy distributes the keys associated with tags across multiple sets, ensuring performance remains high even when a tag has a large number of keys.
- **Atomic Operations**: When a cache key is added or removed, all necessary operations (like updating sets and shards) are executed atomically, ensuring data consistency.

By following this architecture, `laravel-super-cache` is designed to handle high-volume cache operations efficiently while maintaining the flexibility and scalability needed for large enterprise applications.

### Sharding for Efficient Tag Management

[](#sharding-for-efficient-tag-management-1)

[![sharding.webp](resources%2Fimages%2Fsharding.webp)](resources%2Fimages%2Fsharding.webp)Tags are distributed across multiple shards to optimize performance. When a key is associated with a tag, it is added to a specific shard determined by a fast hashing function (crc32). This sharding reduces the performance bottleneck by preventing single large sets from slowing down the cache operations.

### Locks for Concurrency Control

[](#locks-for-concurrency-control)

[![locks.webp](resources%2Fimages%2Flocks.webp)](resources%2Fimages%2Flocks.webp)When a key is processed for expiration, an optimistic lock is acquired to prevent race conditions, ensuring that no concurrent process attempts to alter the same key simultaneously. The lock has a short TTL to ensure it is quickly released after processing.

### Namespace Suffix for Parallel Processing

[](#namespace-suffix-for-parallel-processing)

To handle high volumes of expiry notifications efficiently, the listener processes them in parallel by suffixing namespaces to keys. Each process handles notifications for a specific namespace, allowing for scalable parallel processing. The listener uses batch processing with Lua scripting to optimize performance.

### Redis Expiry Notifications and Listener System

[](#redis-expiry-notifications-and-listener-system)

#### Handling Expire Correctly with TTLs

[](#handling-expire-correctly-with-ttls)

[![expires.webp](resources%2Fimages%2Fexpires.webp)](resources%2Fimages%2Fexpires.webp)To ensure keys are deleted from Redis when they expire, a combination of TTL and expiry notifications is used. If a key expires naturally, the listener is notified to clean up any associated tag sets. This ensures no "orphan" references are left in the cache.

#### Listener for Expiry Notifications

[](#listener-for-expiry-notifications)

[![listener.webp](resources%2Fimages%2Flistener.webp)](resources%2Fimages%2Flistener.webp)The listener is responsible for handling expired cache keys and cleaning up associated tags efficiently by combining Lua scripts, batch processing and Redis pipelines. You can run multiple processes in parallel by setting different {namespace} values. This allows the listener to handle notifications in parallel for optimal performance.

To ensure that keys are cleaned up efficiently upon expiration, `laravel-super-cache` uses Redis expiry notifications in combination with a dedicated listener process. This section explains how the notification system works, how the listener consumes these events, and the benefits of using batching, pipelines, and Lua scripts for performance optimization.

#### Redis Expiry Notifications: How They Work

[](#redis-expiry-notifications-how-they-work)

Redis has a mechanism to publish notifications when certain events occur. One of these events is the expiration of keys (`EXPIRED`). The `laravel-super-cache` package uses these expiry notifications to clean up the tag associations whenever a cache key expires.

**Enabling Expiry Notifications in Redis**:

- Redis must be configured to send `EXPIRED` notifications. This is done by setting the `notify-keyspace-events` parameter to include `Ex` (for expired events).
- When a key in Redis reaches its TTL (Time-To-Live) and expires, an `EXPIRED` event is published to the Redis notification channel.

#### The Listener: Consuming Expiry Events

[](#the-listener-consuming-expiry-events)

The `supercache:listener` command is a long-running process that listens for these `EXPIRED` events and performs clean-up tasks when they are detected. Specifically, it:

1. **Subscribes to Redis Notifications**: The listener subscribes to the `EXPIRED` events, filtered by a specific namespace to avoid processing unrelated keys.
2. **Accumulates Expired Keys in Batches**: When a key expires, the listener adds it to an in-memory batch. This allows for processing multiple keys at once rather than handling each key individually.
3. **Processes Batches Using Pipelines and Lua Scripts**: Once a batch reaches a size or time threshold, it is processed in bulk using Redis pipelines or Lua scripts for maximum efficiency.

### Performance Benefits: Batching, Pipeline, and Lua Scripts

[](#performance-benefits-batching-pipeline-and-lua-scripts)

1. **Batching in Memory**:

    - **What is it?** Instead of processing each expired key as soon as it is detected, the listener accumulates keys in a batch.
    - **Benefits**: Reduces the overhead of individual operations, as multiple keys are processed together, reducing the number of calls to Redis.
2. **Using Redis Pipelines**:

    - **What is it?** A pipeline in Redis allows multiple commands to be sent to the server in one go, reducing the number of network round-trips.
    - **Benefits**: Processing a batch of keys in a single pipeline operation is much faster than processing each key individually, as it minimizes network latency.
3. **Executing Batch Operations with Lua Scripts**:

    - **What is it?** Lua scripts allow you to execute multiple Redis commands atomically, ensuring that all operations on a batch of keys are processed as a single unit within Redis.
    - **Benefits**:
        - **Atomicity**: Ensures that all related operations (e.g., removing a key and cleaning up its associated tags) happen together without interference from other processes.
        - **Performance**: Running a Lua script directly on the Redis server is faster than issuing multiple commands from an external client, as it reduces the need for multiple network calls and leverages Redis’s internal processing speed.

### Parallel Processing with Namespaces

[](#parallel-processing-with-namespaces)

To improve scalability, the listener allows processing multiple namespaces in parallel. Each listener process is assigned to handle a specific namespace, ensuring that the processing load is distributed evenly across multiple processes.

- **Benefit**: Parallel processing enables your system to handle high volumes of expired keys efficiently, without creating a performance bottleneck.

#### Example Workflow: Handling Key Expiry

[](#example-workflow-handling-key-expiry)

1. **Key Expiration Event**: A cache key `product:123` reaches its TTL and expires. Redis publishes an `EXPIRED` event for this key.
2. **Listener Accumulates Key**: The listener process receives the event and adds `product:123` to an in-memory batch.
3. **Batch Processing Triggered**: Once the batch reaches a size threshold (e.g., 100 keys) or a time threshold (e.g., 1 second), the listener triggers the batch processing.
4. **Batch Processing with Lua Script**:
    - A Lua script is executed on Redis to:
        - Verify if the key is actually expired (prevent race conditions).
        - Remove the key from all associated tag sets.
        - Delete the key-tag association set.
    - This entire process is handled atomically by the Lua script for consistency and performance.

### Why This Approach Optimizes Performance

[](#why-this-approach-optimizes-performance)

By combining batching, pipelining, and Lua scripts, the package ensures:

- **Reduced Network Overhead**: Fewer round-trips between your application and Redis.
- **Atomic Operations**: Lua scripts guarantee that all necessary operations for a key's expiry are handled in a single atomic block.
- **Efficient Resource Utilization**: Memory batching allows for efficient use of system resources, processing large numbers of keys quickly.
- **Parallel Scalability**: By using multiple listeners across namespaces, your system can handle large volumes of expirations without creating performance bottlenecks. This approach provides a robust, scalable, and highly performant cache management system for enterprise-grade Laravel applications.

### Scheduled Command for Orphaned Key Cleanup

[](#scheduled-command-for-orphaned-key-cleanup)

Optionally, a scheduled command can be configured to periodically clean up any orphaned keys or sets left due to unexpected interruptions or errors. This adds an additional safety net to maintain consistency across cache keys and tags.

```
php artisan supercache:clean-orphans [--connection_name=]
```

This can be scheduled using Laravel's scheduler to run at appropriate intervals, ensuring your cache remains clean and optimized.

Conclusion
----------

[](#conclusion)

With laravel-super-cache, your Laravel application can achieve enterprise-grade caching performance with robust tag management, efficient key invalidation, and seamless parallel processing. Enjoy a faster, more reliable cache that scales effortlessly with your application's needs.

Change log
----------

[](#change-log)

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

Testing
-------

[](#testing)

```
composer test
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email instead of using the issue tracker.

Credits
-------

[](#credits)

- [Lorenzo Padovani](https://github.com/lopadova)
- [All Contributors](../../contributors)

About Padosoft
--------------

[](#about-padosoft)

Padosoft () is a software house based in Florence, Italy. Specialized in E-commerce and web sites.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

49

—

FairBetter than 94% of packages

Maintenance85

Actively maintained with recent releases

Popularity29

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 63.6% 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 ~16 days

Recently: every ~93 days

Total

36

Last Release

78d ago

Major Versions

v1.0.8 → v2.0-beta.62024-11-28

v1.1.1 → v2.0-beta.72024-12-09

v1.1.2 → v2.0.0-beta2024-12-19

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/10467699?v=4)[Lorenzo](/maintainers/lopadova)[@lopadova](https://github.com/lopadova)

---

Top Contributors

[![januabisconti](https://avatars.githubusercontent.com/u/171591409?v=4)](https://github.com/januabisconti "januabisconti (49 commits)")[![lopadova](https://avatars.githubusercontent.com/u/10467699?v=4)](https://github.com/lopadova "lopadova (14 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (7 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (3 commits)")[![EduardoMateos](https://avatars.githubusercontent.com/u/11529050?v=4)](https://github.com/EduardoMateos "EduardoMateos (3 commits)")[![leopado](https://avatars.githubusercontent.com/u/20923180?v=4)](https://github.com/leopado "leopado (1 commits)")

---

Tags

cachelaravelredisredis-cacherediscacheredis-cachepadosoftlaravel-super-cache

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/padosoft-laravel-super-cache/health.svg)

```
[![Health](https://phpackages.com/badges/padosoft-laravel-super-cache/health.svg)](https://phpackages.com/packages/padosoft-laravel-super-cache)
```

###  Alternatives

[unopim/unopim

UnoPim Laravel PIM

10.5k2.4k](/packages/unopim-unopim)[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k9.0M69](/packages/spatie-laravel-responsecache)[api-platform/laravel

API Platform support for Laravel

58171.5k14](/packages/api-platform-laravel)[awssat/laravel-visits

Laravel Redis visits counter for Eloquent models

973172.3k2](/packages/awssat-laravel-visits)[swayok/alternative-laravel-cache

Replacements for Laravel's redis and file cache stores that properly implement tagging idea. Powered by cache pool implementations provided by http://www.php-cache.com/

202583.7k8](/packages/swayok-alternative-laravel-cache)[iazaran/smart-cache

Smart Cache is a caching optimization package designed to enhance the way your Laravel application handles data caching. It intelligently manages large data sets by compressing, chunking, or applying other optimization strategies to keep your application performant and efficient.

21111.6k](/packages/iazaran-smart-cache)

PHPackages © 2026

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