Master Eloquent caching to minimize database hits. Learn how to wrap model lookups in Redis and automate cache invalidation using Laravel's model events.
Previously in this course, we explored Advanced Indexing Strategies to optimize how the database engine retrieves data. While indexes reduce the cost of a query, the most performant query is the one you never send to the database at all.
In this lesson, we move from optimizing database reads to eliminating them entirely through model-level caching. We will build a robust pattern for caching individual Eloquent instances and ensuring data consistency through automated invalidation.
In a high-traffic SaaS, repetitive lookups for static or semi-static data—like "Plan Settings," "User Profiles," or "Organization Metadata"—account for a massive percentage of your database CPU cycles.
While we’ve previously discussed Caching Strategies for Performance: Mastering Laravel and Redis, applying those concepts to Eloquent requires a disciplined approach to cache keys and lifecycle management. Without a strategy, you end up with "stale data bugs," where a user updates their profile, but the application continues to serve the old cached version.
To keep our architecture clean, we avoid cluttering our Eloquent models with cache logic. Instead, we use a service-based approach to wrap the retrieval process.
Let's assume our SaaS platform frequently fetches a User model by ID. Instead of hitting the DB, we'll check Redis first.
PHPnamespace App\Services; use App\Models\User; use Illuminate\Support\Facades\Cache; class UserService { public function findById(int $id): User { #6A9955">// Use a cache key specific to the model and ID return Cache::remember("user:{$id}", now()->addHours(24), function () use ($id) { return User::findOrFail($id); }); } }
This remember method is the workhorse of Eloquent caching. It checks the key; if it's missing, it executes the closure and stores the result.
The biggest pitfall in caching is the "stale data" trap. When a model is updated or deleted, the cached version is now a lie. Laravel's model events provide the perfect hook for invalidation.
We will use a Trait to keep our models clean and reusable.
PHPnamespace App\Traits; use Illuminate\Support\Facades\Cache; trait Cachable { public static function bootCachable() { static::updated(function ($model) { Cache::forget(static::getCacheKey($model->id)); }); static::deleted(function ($model) { Cache::forget(static::getCacheKey($model->id)); }); } public static function getCacheKey(int $id): string { return strtolower(class_basename(static::class)) . ":{$id}"; } }
Now, simply apply this trait to your User model. Any time you call $user->update(), the cache is automatically purged, forcing the UserService to fetch a fresh copy on the next request.
Cachable trait as shown above.Subscription model.SubscriptionService to use Cache::remember when fetching subscriptions.php artisan tinker to fetch a subscription, then update the database directly via SQL (bypassing the model), and observe that the app still serves the cached version. Then, update the model via Eloquent and observe the cache clear.where filters on that data. Cache individual models or small, specific datasets only.Serialization of 'Closure' is not allowed errors.Cache::remember which handles the lock internally, or consider pre-warming your cache for critical items.By implementing a standardized caching layer for our Eloquent models, we significantly reduce database overhead. The key is to treat the cache as a secondary, volatile store and rely on model events to ensure that the "source of truth" (the database) and the "speed layer" (Redis) stay synchronized.
Up next, we will dive into Queue Worker Prioritization, where we'll learn how to ensure that critical background tasks—like sending password reset emails—are never stuck behind low-priority batch processing.
Master multi-layered caching to scale your Laravel application. Learn to orchestrate Redis, Memcached, and CDN layers for maximum performance and reliability.
Read moreMaster Cache Tags and event-driven invalidation in Laravel. Prevent stale data by implementing granular purging strategies for high-traffic production systems.
Eloquent Caching Strategies
Custom Middleware Development
Database Connection Pooling
Handling Large Data Exports
Security Header Configuration
Database Sharding Concepts
Real-time Data Synchronization
Database Deadlock Prevention
Managing Third-Party API Integrations