3 min read
Caching
Caching sits between your application and its slowest operations — database queries, external API calls, expensive computations. Laravel's cache system is driver-agnostic: the same code works whether you are using files, Redis, Memcached, or a database-backed store.
Cache Drivers
Configure your driver in .env:
CACHE_DRIVER=redis
Common drivers and when to use them:
| Driver | Best for |
|---|---|
file |
Local development, single-server deployments |
redis |
Production, shared across multiple servers |
memcached |
High-throughput scenarios where you do not need persistence |
database |
Simple deployments where Redis is not available |
array |
Tests — fast, in-memory, cleared between requests |
null |
Disabling the cache entirely (useful in CI) |
Basic Operations
use Illuminate\Support\Facades\Cache; // Store a value for 60 seconds Cache::put('user:1', $user, 60); // Retrieve it (returns null if missing) $user = Cache::get('user:1'); // Retrieve with a default fallback $user = Cache::get('user:1', 'not found'); // Check if a key exists if (Cache::has('user:1')) { /* ... */ } // Remove a key Cache::forget('user:1'); // Clear the entire cache Cache::flush();
remember() — The Most Useful Method
remember() combines a get and a put into one call. It fetches the value from cache if it exists; otherwise it runs the closure, stores the result, and returns it:
$categories = Cache::remember('categories', 3600, function () { return Category::with('children')->get(); });
Use rememberForever() when the data rarely changes and you plan to invalidate manually:
$settings = Cache::rememberForever('app_settings', function () { return Setting::all()->keyBy('key'); });
Cache Tags
Tags let you group related cache entries and flush them together. This is especially useful when you want to invalidate all cached data related to a specific entity:
// Store with tags Cache::tags(['articles', 'homepage'])->put('featured_articles', $articles, 3600); // Flush everything tagged 'articles' Cache::tags(['articles'])->flush();
Note: the file and database drivers do not support tags. Use Redis or Memcached if you need them.
Lock-Based Caching
If multiple processes might try to populate the same cache key simultaneously, use a lock to prevent a thundering herd:
$result = Cache::lock('generate-report', 10)->get(function () { // Only one process runs this at a time return generateExpensiveReport(); });
When to Cache
Cache is most valuable for:
- Database queries that return the same data across many requests (navigation menus, config values, lookup tables).
- External API responses that do not change frequently.
- Rendered HTML fragments that are expensive to build.
Avoid caching data that is user-specific or changes on every request — it adds complexity without a performance gain.
Tips
- Set cache TTLs (time-to-live) conservatively at first. It is easier to shorten a TTL than to track down stale data.
- Use a consistent key-naming convention (e.g.,
:{id}:{data}) to make debugging and manual cache inspection straightforward. - In tests, set
CACHE_DRIVER=arrayso each test starts with a clean cache and you do not accidentally depend on cached state from a previous test. - Combine caching with Laravel's
config:cacheandroute:cachein production for maximum bootstrap performance.
Related
- Cache Invalidation Strategies in Laravel — tag-based invalidation, model observer patterns, and TTL strategies for keeping the cache in sync
- Performance Improvements in Laravel — caching in context alongside query optimisation and config/route caching