Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cache Laravel Package

grafite/cache

Grafite Cache is a lightweight Laravel package that simplifies working with cached data through a clean, expressive API. It helps you store, retrieve, and forget values quickly, reducing boilerplate in controllers and services while keeping caching consistent across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

The package plugs an SQLite-backed store into Laravel's cache layer, so the day-to-day API is the same Cache facade you already use — only the storage backend changes.

Minimal steps:

composer require grafite/cache
php artisan vendor:publish --provider="Grafite\Cache\CacheServiceProvider"

Check composer.json / src/ for the exact provider namespace before publishing; with a package this small, the namespace is the first thing to confirm.

Then decide how you want to adopt it. Two options:

  1. Replace the default store — set CACHE_DRIVER=sqlite (or whatever key the provider registers) in .env. Fast to try, but it changes caching for the whole app.
  2. Add as a secondary store (recommended) — register it under config/cache.php → stores.sqlite and address it explicitly:
Cache::store('sqlite')->remember('reports.daily', 600, fn () => Report::daily());

Where to look first:

  • config/cache.php after publishing — the store key, the SQLite path, and the default TTL.
  • The store class itself (it implements Illuminate\Contracts\Cache\Store) — read get/put/forget to see how TTLs and serialization actually work.
  • php artisan cache:clear behavior against the new store — verify it truncates rather than erroring.

First use case: cache an expensive aggregate that is read often and written rarely — dashboard counters, report snapshots, sitemap payloads, third-party API responses. That is where a file-local SQLite cache shines over Redis (no extra service) and over the file driver (you can query it, inspect it, and index it).

Implementation Patterns

Keep the call sites driver-agnostic. Because it implements the standard Store contract, Cache::remember, put, forever, forget, and increment behave as expected. Write your application code against the facade, not the concrete class, so you can swap back to redis or array without edits:

$value = Cache::store('sqlite')->remember("user.{$id}.stats", now()->addMinutes(15), function () use ($id) {
    return $this->calculateStats($id);
});

Use it as the "big, cheap, local" tier. A common pattern is a two-tier setup: array/redis for hot, short-lived lookups and sqlite for larger payloads (rendered HTML fragments, serialized API responses, report rows) that need to survive restarts but don't justify a network hop.

Cache whole query results, not models. Serialize plain arrays or DTOs. Eloquent models cached in a file store become stale the moment the schema or accessors change, and rehydration cost can exceed the query you were avoiding.

Namespace your keys by deploy. Include the release or a schema version in the key prefix so a deploy invalidates logically without a manual flush:

$key = sprintf('v%s.report.%s', config('app.version'), $slug);

Warm and prune on a schedule. Pair writes with a scheduled command that pre-populates the keys your traffic hits first, and a separate cache:prune-stale-tags-style cleanup (or a direct DELETE WHERE expiry < ? against the SQLite file) so the table doesn't grow unbounded. Check whether the package ships a prune command before writing your own.

Testing. Swap to the array driver in phpunit.xml as usual. If you specifically need to test the SQLite store, point the config at :memory: — but note that :memory: is per-connection, so it will not survive across connections in a test suite unless the store opens a fresh one each time.

Wrap it in a repository if you use the "extra features." Anything beyond the Store contract — tags, collections, whatever the package adds — should be behind your own small service class. That isolates you from the package's API if it goes unmaintained.

Gotchas and Tips

Multi-server deployments are the big one. SQLite is a local file. On a multi-node setup behind a load balancer, each node has its own cache with its own invalidation. Either mount a shared volume (and accept the locking cost) or restrict this store to single-node / cron-worker / CLI contexts. Do not use it for anything that requires cluster-wide consistency, like rate limiting or session data.

Concurrency and locking. SQLite serializes writers. Under parallel writes you will see database is locked errors. Enable WAL mode and a busy timeout on first connect (PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000;) if the package doesn't do it for you. If you cannot set pragmas, treat this store as write-light.

File permissions and paths. The SQLite file needs to be writable by the PHP-FPM user, and the directory too (SQLite creates -wal and -shm siblings). Default to storage_path('framework/cache/...') rather than the package's fallback, and make sure your deploy excludes it from git and from rsync of stale caches.

TTL units. Laravel accepts DateTimeInterface, DateInterval, or an integer number of seconds — the common remember($key, 10, ...) mistake (meaning 10 seconds, not minutes) is on you, not the package. Check whether the store's put rounds or floors sub-second TTLs.

Serialization surprises. A file-backed store typically serialize()s values. That means closures, resources, and objects with unserializable state will fail on write. It also means cached payloads carry a size penalty — keep entries in the kilobyte-to-low-megabyte range, not tens of megabytes.

Key hygiene. Long or non-ASCII keys may be hashed or truncated depending on implementation. Avoid raw user input in keys; hash it (hash('xxh128', $input)) to keep keys short and SQLite indexes efficient.

Debugging is unusually pleasant. Unlike Redis or memcached, you can just look:

sqlite3 storage/framework/cache/cache.sqlite ".tables"
sqlite3 storage/framework/cache/cache.sqlite "select key, expiry from cache order by expiry desc limit 20;"

This alone makes it a good choice for debugging cache-stampede issues in staging.

Flush semantics. Confirm what Cache::store('sqlite')->flush() does — dropping all rows vs. dropping and recreating the table — before calling it in a deploy script. On a shared file that can briefly block readers.

Maintenance risk. Zero stars and zero dependents means no community buffer. Audit the source (it is small), pin the version in composer.json, and keep a thin adapter layer so replacing it with a custom Store implementation or the built-in database cache driver is a one-file change. Laravel's own database driver covers much of the same ground with a table you control — benchmark against it before committing.

Extension points. The provider registers the driver via Cache::extend; you can override the store class in config/cache.php per store, and publish the config to point at a different SQLite file. If you need tags and the package doesn't support them, wrap the store in your own class that prefixes keys and tracks them in a side table rather than forking the package.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console