Caching in Laravel
An overview of Laravel's cache system covering cache drivers, storing and retrieving data, cache tags, and common caching patterns to boost performance.
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.,
{entity}:{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
Newsletter
A weekly newsletter on React, Next.js, AI-assisted development, and engineering. No spam, unsubscribe any time.