Lada Cache makes query caching automatic for Laravel on Redis
A Redis based, fully automated and scalable database cache layer for Laravel
At a glance
- What is it?
- Lada Cache is a Laravel package that intercepts database queries at the connection layer, caches the results in Redis, and invalidates only the affected rows when data changes, with no code changes required after setup. It is MIT licensed, and the 6.x line targets Laravel 12 and 13 on PHP 8.3.
- Who is it for?
- Lada Cache suits a Laravel application whose pages repeat the same expensive queries and whose team does not want to hand-maintain cache keys, since the connection-level interception means invalidation happens on writes without touching application code.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 151 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem it is aimed at
Lada Cache is a Redis-based, fully automated, and scalable query cache layer for Laravel, and the reasoning behind it starts with the database-heavy application.
Database-heavy apps, especially with Eloquent, often repeat the same queries and not all are efficient. That is the opening observation in the README's Why section, and it is the condition under which the rest of the design makes sense.
The comparison it draws is with the alternatives a Laravel developer already has. RDBMS internal caches, with MySQL Query Cache as the example, have hard limits: they do not cache multi-table queries such as joins, they invalidate coarsely so that a row change can evict a whole table, they are not distributed across database servers, and they scale poorly under load. Laravel manual caching, by contrast, requires manual invalidation or time-based expiry, which means every developer has to remember to do it.
The problem with manual expiry is worth dwelling on. A cache entry that expires too early wastes the work, and one that expires too late serves stale data, and the second failure is the one that reaches users. Lada Cache's answer is to make invalidation a consequence of the write rather than a separate act of discipline.
The last line of the Why section states the pitch in one sentence: automated, granular, distributed caching with transparent invalidation and scale-out via Redis.
The topics list names cache, caching, database, eloquent, laravel, laravel-package, php and redis, the primary language is PHP, and the licence is MIT.
How the interception works
The architecture section describes the mechanism in five steps, and the first one is the whole design.
Lada Cache integrates with Laravel's database layer by registering a Lada-aware connection, which returns a custom query builder to intercept and cache SQL operations automatically.
So the package replaces the connection rather than asking the application to call a cache function. That is why the README can say that no code changes or caching calls are required, and why all database queries are transparently cached and invalidated. Nothing in the application code says which queries are cacheable, because the package decides that by inspecting the SQL.
The query lifecycle is:
1. Intercept query, and the Reflector analyzes SQL, bindings, and affected tables. 2. Compute cache key, based on SQL plus parameters plus database. 3. Lookup in Redis, and if cached, return immediately. 4. Execute and store, so if not cached, the query runs and the result is stored. 5. Auto-invalidate, on any insert, update, delete, or truncate.
Step five is what makes the granular invalidation claim work, and step two explains how it can be granular. Because the cache key is derived from the SQL, the bindings and the database, two different queries never collide, and because the Reflector identifies the affected tables, a write can be traced back to the keys that depend on them.
The features list names the same mechanism from another angle, with connection integration described as DB queries passing through a Lada-aware connection subclass transparently. It also notes the fine-grained control, namely the ability to include or exclude tables from caching, and the Laravel Debugbar integration for visualising cache hits, misses, and invalidations.
One detail in the feature list is easy to skim past and matters for anyone with a large schema: the package is transparent with Eloquent and Query Builder, which means it applies to both, and the include or exclude tables setting is the escape hatch for the tables where automatic behaviour is not what you want.
Installing it and turning it on
The install path is three steps, and only the third one touches your code.
First, install via Composer:
composer require spiritix/lada-cacheThe package registers itself automatically via Laravel Package Discovery, so there is no service provider to add to a config file.
Second, publish the config file:
php artisan vendor:publish --provider="Spiritix\LadaCache\LadaCacheServiceProvider"That gives you a comprehensive config file at config/lada-cache.php, where you can enable or disable Lada Cache globally, set key prefixes and expiration times, define which tables to include or exclude from caching, and enable Debugbar integration for cache inspection. The README's claim is that the default configuration is already optimized for most Laravel applications, so you typically will not need to modify it unless you want more granular control.
Third, ensure all your Eloquent models include the trait:
use Spiritix\LadaCache\Database\LadaCacheTrait;
class Car extends Model
{
use LadaCacheTrait;
}The README adds a recommendation that is worth taking: it is best to add the trait in a shared BaseModel class that all models extend. That way a new model inherits caching behaviour instead of someone remembering to add the line.
The global switch lives in your .env file, and it takes two variables:
LADA_CACHE_ACTIVE=true
LADA_CACHE_DEBUGBAR=trueSetting LADA_CACHE_ACTIVE to false before deploying is the safe first step, because it lets you verify that the application behaves identically with the layer present but inert, which is a different question from whether it behaves identically when the layer is doing its job.
The repository also ships a Dockerfile, a docker-compose.yml and a Makefile for running the test suite against both SQLite and MySQL, which is the way to check the package on the database engine your application actually uses.
Bypassing the cache for a single query
Automatic caching needs an escape hatch, and the package provides one that works at query level in both the Eloquent and the Query Builder styles.
// Eloquent
$user = User::where('id', $id)->withoutCache()->first();
// Query Builder
DB::table('users')->where('id', $id)->withoutCache()->update(['name' => 'New']);The semantics are stated precisely, and the precision matters. The query skips both read caching and write invalidation, then continues through Laravel as usual.
Skipping write invalidation as well as read caching is the correct choice, and it is the part that is easy to get wrong in a hand-rolled implementation. If a write bypassed caching but still invalidated, you would get a cache flush with no benefit. If a write was cached but skipped invalidation, the cache would serve a stale value that nothing will ever replace. Doing both or neither keeps the two consistent.
The README gives the use cases as freshness-critical reads, diagnostics, and ad-hoc cache busting without touching the configuration.
There is also a coarser control for operational situations, three Artisan commands:
# Flush all cached entries
php artisan lada-cache:flush
# Temporarily disable cache
php artisan lada-cache:disable
# Re-enable cache
php artisan lada-cache:enableThe flush command is the one you will reach for when something looks wrong and you need a clean state without a deploy, and the disable and enable pair is the emergency switch for when the caching layer itself appears to be the problem.
Version compatibility and the 6.x rewrite
The README puts a banner above the table of contents that sets the frame for the current release.
Lada Cache 6.x, a focused rewrite for Laravel 12 / 13 and PHP 8.3, addressing many long-standing issues and adding new features.
The compatibility table maps each Laravel line to a PHP floor and a Lada Cache major version, and it is the most useful single piece of information in the repository for anyone arriving with an existing application:
Laravel 5.1 through 5.6 pairs with PHP 5.6.4 or later and Lada Cache 2.x. Laravel 5.7 and 5.8 pair with PHP 7.1 or later and 3.x. Laravel 6.x pairs with PHP 7.2 or later and 4.x. Laravel 7.x and 8.x pair with 7.2 and 7.3 respectively, both on 5.x. Laravel 9.x through 11.x pair with PHP 8.0 or later on 5.x. And Laravel 12.x and 13.x both pair with PHP 8.3 or later on 6.x.
Read that table as a statement about upgrade cost as much as about compatibility. A project on Laravel 8 cannot move to Lada Cache 6.x without also moving to Laravel 12, which means a major Laravel upgrade as a precondition for the current Lada Cache line. The compatibility surface is deliberately narrow, and the 6.x rewrite is where the PHP 8.3 floor comes from.
The release history backs up the sense of a recently reworked package: v6.0.3 on 2025-11-11, v6.1 on 2026-03-21 and v6.1.1 on 2026-05-22, with the last push on 2026-05-25.
The table of contents also lists sections the README does not expand on, which tells you where the documentation lives rather than leaving you to guess. There is a Contributing section pointing at the repository's contribution guidelines, and a license section naming the MIT License.
Where Lada Cache fits, and where it stops
The comparison worth making is with Laravel's own cache layer, and with the alternative of doing nothing but fixing the queries.
Against Laravel's cache facade, the difference is who decides what to cache. Manual caching means a developer writes the key, writes the retrieval, and writes the invalidation, and the third of those is the one that gets forgotten until a user reports stale data. Lada Cache computes the key from the SQL and the bindings, and invalidates on the write, so the developer writes nothing. The cost is that you give up control over granularity, which is why the table include and exclude setting exists and why withoutCache() is there.
Against just fixing the queries, the difference is where the effort goes. Rewriting a slow query in Eloquent with eager loading usually beats caching it, because it removes the work rather than repeating it less often. Lada Cache's own performance section is candid about the trade-off, noting that real-world gains range from 5% to 95% depending on how many and how complex your queries are, with typical Laravel apps seeing around 10 to 30% faster responses and a significant drop in DB load. It also notes that large payloads still cost to move and encode, and gives the case of a query returning roughly 500MB which will not get faster from caching alone.
The known issues section is where the real limits are, and it is worth reading before you enable this in production. Multiple connections such as DB::connection('foo') are only supported when using Lada's connection integration, while models defining $connection work automatically. Third-party packages with custom query builders may bypass caching entirely, since the interception happens at the query builder level and a package that supplies its own builder replaces the one Lada hooks. And complex SQL constructs such as UNION, INTERSECT and advanced expressions may not be fully reflected for row-level tagging, which means invalidation for those queries can be coarser than the granularity the package otherwise offers.
The Redis-only decision is stated as a requirement rather than a preference: in-memory storage for latency and throughput, easy scalability and distribution, and tagging support for granular invalidation, with the note that Laravel Cache tags exist but are slow for this use case. The README says contributions are welcome if you need another backend, which is an invitation rather than a plan.
The honest summary is that Lada Cache is a well-scoped tool for a Laravel application with repeated expensive reads, on a recent Laravel version, where the team wants invalidation to be automatic and accepts that a handful of edge cases will be handled coarsely. It is a poor fit for a small app with a handful of queries, where the extra Redis dependency and the per-query key computation cost more than they save.
Editorial conclusion
Lada Cache suits a Laravel application whose pages repeat the same expensive queries and whose team does not want to hand-maintain cache keys, since the connection-level interception means invalidation happens on writes without touching application code. It is the wrong tool for an app with few repeated queries, since the caching layer adds a Redis dependency and a key computation to every query, and it is the wrong tool where correctness depends on complex SQL, because the README says constructs such as UNION and INTERSECT may not be fully reflected for row-level tagging. Before enabling it, add the trait to a shared base model, set LADA_CACHE_ACTIVE in your .env file, and confirm your queries run under the Lada-aware connection rather than a custom query builder from a third-party package.
Frequently asked questions
What is Lada Cache and how does it work?
Lada Cache is a Redis-based, fully automated and scalable query cache layer for Laravel. It registers a Lada-aware connection that returns a custom query builder, so queries are intercepted, keyed by SQL plus parameters plus database, looked up in Redis, and invalidated automatically on any insert, update, delete or truncate.
How do I install Lada Cache in Laravel?
Run composer require spiritix/lada-cache, which registers the package through Laravel Package Discovery, then publish the config with php artisan vendor:publish --provider="Spiritix\LadaCache\LadaCacheServiceProvider", and add the LadaCacheTrait to your Eloquent models. The README suggests putting the trait in a shared base model that all models extend.
How do I disable the cache for a single query?
Call withoutCache() on the query, for example User::where('id', $id)->withoutCache()->first() in Eloquent or DB::table('users')->where('id', $id)->withoutCache()->update(['name' => 'New']) with the Query Builder. The query skips both read caching and write invalidation and continues through Laravel as usual.
Which Laravel and PHP versions does Lada Cache 6.x support?
Lada Cache 6.x targets Laravel 12 and 13 on PHP 8.3 or later, and is described as a focused rewrite for those versions. Older combinations use earlier lines: Laravel 9.x to 11.x with PHP 8.0 on 5.x, Laravel 7.x and 8.x on 5.x, Laravel 6.x on 4.x, and Laravel 5.x on 2.x and 3.x.
Why does Lada Cache only support Redis?
The README gives three reasons: in-memory storage for latency and throughput, easy scalability and distribution, and tagging support for granular invalidation, noting that Laravel Cache tags exist but are slow for this use case. Lada Cache therefore builds directly on Laravel Redis, and the README says contributions are welcome if another backend is needed.
What are the known limitations of Lada Cache?
Multiple connections such as DB::connection('foo') are only supported with Lada's connection integration, though models defining $connection work automatically. Third-party packages with custom query builders may bypass caching, and complex SQL constructs such as UNION and INTERSECT may not be fully reflected for row-level tagging.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/spiritix-lada-cache)Was this useful?