QueryCache

QueryCache is a general query result caching system for Eloquent models. It's optimized to be as automated as possible, and can work with Redis and SQLite as caching.

Installation

First, publish the configuration file:

php artisan vendor:publish --provider="Grafite\QueryCache\QueryCacheProvider"

Next, add the following to your .env file to configure the package:

QUERY_CACHE_TTL=604800 // 7 days
QUERY_CACHE_FLUSH_ON_UPDATE=true
QUERY_CACHE_DRIVER=redis
QUERY_CACHE_PREFIX=qc
QUERY_CACHE_PLAIN_TEXT_KEYS=false
QUERY_CACHE_PREVENT_STAMPEDE=false
QUERY_CACHE_MEMOIZE=true
QUERY_CACHE_MEMOIZE_LIMIT=1000
QUERY_CACHE_SKIP_IN_TRANSACTIONS=true

QUERY_CACHE_PREVENT_STAMPEDE and QUERY_CACHE_MEMOIZE are optional optimizations. QUERY_CACHE_PREVENT_STAMPEDE guards against cache stampedes when many requests miss the cache at the same time, while QUERY_CACHE_MEMOIZE serves repeated identical queries within a single request from memory instead of hitting the cache backend each time.

QUERY_CACHE_MEMOIZE_LIMIT caps how many memoized results are held per request (default 1000), evicting the oldest first, so long-running commands and queue workers stay bounded.

Next, add the QueryCacheable trait to any Eloquent model you wish to cache queries for.

With the trait added you have access to the following methods:

static bool flushQueryCache(array $tags = [])
static bool flushQueryCacheWithTag(string $string)
static \Illuminate\Database\Query\Builder|static cacheFor(\DateTime|int|null $time)
static \Illuminate\Database\Query\Builder|static cacheForever()
static \Illuminate\Database\Query\Builder|static dontCache()
static \Illuminate\Database\Query\Builder|static doNotCache()
static \Illuminate\Database\Query\Builder|static cacheDriver(string $cacheDriver)
static \Illuminate\Database\Query\Builder|static cacheBaseTags(array $tags = [])

Important Details

By default, QueryCache will flush the cache for a model when it is created, updated, or deleted. This behavior can be disabled by setting QUERY_CACHE_FLUSH_ON_UPDATE to false in your .env file.

If you need to purge the cache manually, you can use the flushQueryCache method on your model.

Transactions

Queries run inside a database transaction bypass the cache, since they may see uncommitted data. Cache flushes triggered by model writes inside a transaction are deferred until it commits, and all writes in that transaction share a single flush. A rollback flushes nothing.

Set QUERY_CACHE_SKIP_IN_TRANSACTIONS to false to cache inside transactions, for example when your test suite wraps every test in one.

Upgrading

As of v1.6, hashed cache keys use xxh128 instead of md5, so existing cached queries will miss once after upgrading.