Laravel Cache Deep — Advanced Cache Strategies and Drivers
In this tutorial, you will learn about Laravel Cache Deep. We cover key concepts, practical examples, and best practices to help you master this topic.
Laravel cache provides a unified API across Redis, Memcached, database, and file drivers with support for cache tags, atomic locks, cache helpers, and cache events.
What You'll Learn
By the end of this tutorial, you'll configure Redis and Memcached, use cache tags for organized invalidation, implement atomic locks, leverage cache helpers, and design cache strategies.
Why Caching Matters
Caching reduces database load, improves response times, and handles traffic spikes. Proper caching strategies differentiate scalable applications from slow ones.
Real-World Use
An e-commerce site caches product listings with tags per category. When a product price changes, only the relevant category cache is invalidated, not the entire cache.
Cache Path
flowchart LR
A[Laravel Framework] --> B[Cache Deep]
B --> C[Redis]
B --> D[Tags]
B --> E[Locks]
B --> F[Strategies]
B --> G{You Are Here}
style G fill:#f90,color:#fff
Cache Drivers
Configure and use cache drivers.
<?php
// config/cache.php
"stores" => [
"redis" => [
"driver" => "redis",
"connection" => "cache",
"lock_connection" => "default",
],
"memcached" => [
"driver" => "memcached",
"servers" => [
["host" => "127.0.0.1", "port" => 11211, "weight" => 100],
],
],
"database" => [
"driver" => "database",
"table" => "cache",
"connection" => null,
],
],
Cache Tags
Organize cached items with tags for selective invalidation.
<?php
use Illuminate\Support\Facades\Cache;
// Store with tags (Redis or Memcached only)
Cache::tags(["products", "category-5"])->put("products.list", $products, 3600);
Cache::tags(["products", "category-12"])->put("products.list", $products, 3600);
// Retrieve
$products = Cache::tags(["products", "category-5"])->get("products.list");
// Invalidate all products in category 5
Cache::tags(["products", "category-5"])->flush();
// Invalidate all products
Cache::tags(["products"])->flush();
Atomic Locks
Prevent race conditions with distributed locks.
<?php
use Illuminate\Support\Facades\Cache;
// Acquire a lock
$lock = Cache::lock("order-import", 10);
if ($lock->get()) {
try {
// Exclusive operation
Order::importFromApi();
} finally {
$lock->release();
}
}
// Blocking lock
$lock = Cache::lock("report-generation", 30);
$lock->block(5); // Wait up to 5 seconds
try {
GenerateReport::dispatch();
} finally {
$lock->release();
}
Cache Helpers
Use convenient cache helper functions.
<?php
// Remember: Get from cache or store forever
$users = Cache::remember("active.users", 3600, fn() => User::active()->get());
// Remember forever
$config = Cache::rememberForever("app.config", fn() => loadConfig());
// Pull: Get and delete
$token = Cache::pull("reset-token-{$userId}");
// Add: Only set if key does not exist
$lockAcquired = Cache::add("processing-{$orderId}", true, 10);
// Increment/Decrement
Cache::increment("page.visits", 1);
Cache::decrement("stock.{$productId}", 1);
Cache Strategies
Common caching patterns for Laravel.
<?php
// Cache-aside pattern
function getProduct(int $id): Product {
return Cache::remember("product.{$id}", 3600, fn() =>
Product::with(["category", "reviews"])->findOrFail($id)
);
}
// Cache invalidation with model events
class Product extends Model {
protected static function booted(): void {
static::saved(fn(Product $p) => Cache::forget("product.{$p->id}"));
static::deleted(fn(Product $p) => Cache::forget("product.{$p->id}"));
}
}
// Cache pagination
public function index(): View {
$page = request()->get("page", 1);
$products = Cache::remember("products.page.{$page}", 300, fn() =>
Product::paginate(20)
);
return view("products.index", compact("products"));
}
Common Mistakes
1. Caching Too Much Data
Large cached objects use memory. Cache only the data needed for the response.
2. Not Setting TTL
Cached items without TTL stay forever. Always set an expiration time.
3. Cache Stampede
Multiple requests simultaneously regenerate the cache. Use Cache::lock() to prevent stampedes.
4. Using Tags with File/Database Drivers
Cache tags only work with Redis and Memcached. Other drivers silently ignore tags.
5. Not Invalidating on Data Changes
Stale data is worse than no cache. Invalidate caches when underlying data changes.
Practice Questions
1. What are cache tags used for?
Grouping cached items for selective invalidation.
2. How do atomic locks prevent race conditions?
They ensure only one Process executes a Critical Section at a time.
3. What is Cache::remember()?
Get the value if cached, otherwise store the callback result and return it.
4. Which drivers support cache tags?
Redis and Memcached only.
5. Challenge: Implement cache-aside with tag-based invalidation.
<?php
class ProductCache {
public function get(int $id): Product {
return Cache::tags(["products", "product.$id"])
->remember("product.$id", 3600, fn() => Product::findOrFail($id));
}
public function invalidate(int $id): void {
Cache::tags(["product.$id"])->flush();
}
}
FAQ
Mini Project: Caching Layer for API
Build a caching layer for a Laravel API.
<?php
class CachedProductService {
public function list(int $page, int $categoryId): Collection {
return Cache::tags(["products", "cat.$categoryId"])
->remember("products.list.$page.$categoryId", 600, fn() =>
Product::whereCategoryId($categoryId)->paginate(20)
);
}
public function show(int $id): Product {
return Cache::tags(["product.$id"])
->remember("product.$id", 600, fn() =>
Product::with(["reviews", "category"])->findOrFail($id)
);
}
}
What's Next
Laravel Session Laravel Queues Deep Eloquent Performance
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro