Learn how to use caching in Laravel to slash database load. Master cache tags, store configuration, and invalidation strategies for high-performance apps.
Previously in this course, we covered Eloquent Performance Optimization to eliminate N+1 query issues. While eager loading is a mandatory first step, some operations—like calculating complex project statistics or fetching global settings—remain expensive no matter how well you optimize your SQL.
Today, we move beyond the database layer by implementing caching. We’ll focus on using Redis to store computed results, using cache tags for granular control, and ensuring your cache stays fresh through proper invalidation.
Every time a user requests your project board, the server performs a round-trip to the database, deserializes rows into Eloquent models, and transforms them into JSON. On a high-traffic app, this is a bottleneck.
Caching is the practice of storing the result of an expensive operation in a fast, volatile storage medium (like RAM) so subsequent requests can skip the heavy lifting. In Laravel, we use the Cache facade to abstract this process, allowing us to swap drivers like file, database, or redis without changing our application logic.
Laravel allows you to define multiple stores in config/cache.php. For production, Redis is the industry standard because it’s an in-memory data structure store that supports atomic operations and complex data types.
To use Redis, ensure you have the predis/predis or phpredis extension installed and update your .env:
BashCACHE_STORE=redis REDIS_CLIENT=phpredis
Now, you can interact with the store directly:
PHP#6A9955">// Storing data for 60 minutes Cache::store('redis')->put('project_stats_1', $data, now()->addMinutes(60)); #6A9955">// Retrieving with a fallback closure $stats = Cache::store('redis')->remember('project_stats_1', 3600, function () { return Project::calculateComplexStats(); });
A common mistake is caching everything under a single key. When the underlying data changes, you're forced to clear the entire cache. Cache tags solve this by allowing you to group related cache items and purge them collectively.
Note: Cache tags are only supported by drivers like redis or memcached.
Imagine our project board has a list of tasks. We want to cache the tasks for a specific project, but we also want to cache them under a "tasks" tag so we can clear all task-related caches if a global update occurs.
PHP#6A9955">// Tagging cache items Cache::tags(['projects', 'tasks'])->put('project_1_tasks', $tasks, 3600); #6A9955">// Retrieving tagged items $tasks = Cache::tags(['projects', 'tasks'])->get('project_1_tasks'); #6A9955">// Invalidating everything under the 'projects' tag Cache::tags(['projects'])->flush();
Caching is easy; cache invalidation is where most engineers fail. If you cache a project’s task list but don't clear it when a task is added, the user sees stale data.
We solve this using observers or events. In our project board, every time a Task is created or updated, we must clear the relevant cache.
PHP#6A9955">// Inside a TaskObserver public function saved(Task $task) { #6A9955">// Clear the specific project cache tag Cache::tags(['project_' . $task->project_id])->flush(); }
This pattern ensures that the cache is always eventually consistent with the database. You can read more about managing complex dependencies in Database Caching Strategies: Mastering Partitioned Keys and Eviction to see how this scales.
In our ongoing project board, open your TaskService.
Cache::tags(['project_' . $projectId])->remember(...) block.TaskObserver and use the saved and deleted hooks to flush the project_{id} tag.Performance requires a multi-layered approach. By moving expensive calculations into Redis using cache tags, we reduce the load on our primary database. Remember: cache invalidation is the most critical part of the strategy—if your data is stale, the performance gain is irrelevant.
Up next: We’ll explore how to clean up our code further by Using Traits for Code Reuse, allowing us to share common caching and logic patterns across our models and services.
Master OAuth2 implementation in Laravel by building a secure Authorization Code flow. Learn to handle token issuance, validation, and architectural best practices.
Caching Strategies for Performance