Laravel 11 Caching Mastery: From Basics to Advanced Techniques

Abu Sayed
5 min readJul 25, 2024

--

Unlock the power of Laravel 11 caching with our comprehensive guide. Learn real-life use cases, advanced techniques, and best practices to supercharge your application’s performance.

Laravel 11 Caching Mastery: From Basics to Advanced Techniques

Laravel 11 Caching: Boosting Performance with Real-Life Examples

In the world of web development, performance is king. As our applications grow in complexity and user base, the need for efficient data retrieval and processing becomes paramount. This is where caching comes into play, and Laravel 11 offers a robust and flexible caching system that can significantly improve your application’s performance. In this comprehensive guide, we’ll explore Laravel 11 caching from the ground up, covering basic concepts, real-life use cases, and advanced techniques.

Introduction to Caching in Laravel 11

Caching is the process of storing frequently accessed data in a fast-access storage layer, reducing the need for expensive database queries or API calls. Laravel provides a unified API for various caching backends, making it easy to implement caching in your application regardless of the underlying storage mechanism.

Basic Caching Concepts

Before we dive into real-life examples, let’s review some basic caching methods in Laravel 11:

Retrieving and Storing Items

use Illuminate\Support\Facades\Cache;
// Storing an item in the cache
Cache::put('key', 'value', $seconds);
// Retrieving an item from the cache
$value = Cache::get('key');
// Retrieving with a default value
$value = Cache::get('key', 'default');
// Storing an item indefinitely
Cache::forever('key', 'value');
// Checking if an item exists in the cache
if (Cache::has('key')) {
// Item exists
}
// Removing an item from the cache
Cache::forget('key');

Cache Helper Function

Laravel also provides a global cache helper function:

$value = cache('key');
cache(['key' => 'value'], $seconds);

Now that we’ve covered the basics, let’s explore real-life use cases and advanced caching techniques.

Real-Life Use Cases with Examples

1. Caching Database Queries

One of the most common use cases for caching is to store the results of expensive database queries.

Example: Caching a List of Popular Products

use App\Models\Product;
use Illuminate\Support\Facades\Cache;
class ProductController extends Controller
{
public function getPopularProducts()
{
return Cache::remember('popular_products', 3600, function () {
return Product::where('is_popular', true)
->with('category')
->orderBy('views', 'desc')
->take(10)
->get();
});
}
}

In this example, we’re caching the list of popular products for one hour (3600 seconds). The remember method checks if the cache exists; if not, it executes the closure and stores the result.

2. Caching API Responses

When working with external APIs, caching responses can significantly reduce load times and API usage.

Example: Caching Weather Data

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
class WeatherController extends Controller
{
public function getWeather($city)
{
return Cache::remember("weather_{$city}", 1800, function () use ($city) {
$response = Http::get("https://api.weatherapi.com/v1/current.json", [
'key' => config('services.weather.key'),
'q' => $city,
]);
return $response->json();
});
}
}

This example caches weather data for a specific city for 30 minutes (1800 seconds), reducing the number of API calls to the weather service.

3. Fragment Caching

Fragment caching allows you to cache specific parts of your views, which is useful for dynamic content that doesn’t change frequently.

Example: Caching a Product Reviews Section

<!-- In your Blade template -->
@php
$cacheKey = "product_{$product->id}_reviews";
@endphp
@cache($cacheKey, 3600)
<div class="product-reviews">
@foreach($product->reviews as $review)
<div class="review">
<h4>{{ $review->title }}</h4>
<p>{{ $review->content }}</p>
</div>
@endforeach
</div>
@endcache

This caches the product reviews section for an hour, reducing database queries for frequently viewed products.

Advanced Caching Techniques

1. Cache Tags

Cache tags allow you to tag related items in the cache and clear all tagged items at once.

Example: Tagging and Clearing User-Specific Caches

use Illuminate\Support\Facades\Cache;
class UserController extends Controller
{
public function getUserData($userId)
{
return Cache::tags(['users', "user-{$userId}"])->remember("user_data_{$userId}", 3600, function () use ($userId) {
return User::with('posts', 'comments')->find($userId);
});
}
public function updateUser(Request $request, $userId)
{
// Update user data
User::find($userId)->update($request->validated());
// Clear all caches related to this user
Cache::tags(["user-{$userId}"])->flush();
return response()->json(['message' => 'User updated successfully']);
}
}

In this example, we’re tagging user-specific caches. When a user is updated, we can easily clear all caches related to that user.

2. Cache Locks

Cache locks prevent race conditions when multiple requests attempt to update the same cached item simultaneously.

Example: Implementing a Rate Limiter

use Illuminate\Support\Facades\Cache;
class RateLimiter
{
public function attempt($key, $maxAttempts, $decaySeconds)
{
return Cache::lock("rate_limiter_{$key}", 10)->block(5, function () use ($key, $maxAttempts, $decaySeconds) {
$attempts = (int) Cache::get($key, 0);
if ($attempts >= $maxAttempts) {
return false;
}
Cache::put($key, $attempts + 1, $decaySeconds);
return true;
});
}
}

This rate limiter uses a cache lock to ensure that only one process can update the attempt count at a time, preventing race conditions in high-concurrency scenarios.

3. Lazy Collections with Caching

Lazy collections in Laravel allow you to work with large datasets efficiently. Combined with caching, they can provide powerful performance optimizations.

Example: Caching Paginated Results

use Illuminate\Support\LazyCollection;
use Illuminate\Support\Facades\Cache;
class ProductController extends Controller
{
public function index($page = 1)
{
$perPage = 20;
$offset = ($page - 1) * $perPage;
return Cache::remember("products_page_{$page}", 3600, function () use ($perPage, $offset) {
return LazyCollection::make(function () {
$cursor = Product::cursor();
foreach ($cursor as $product) {
yield $product;
}
})
->slice($offset, $perPage)
->all();
});
}
}

This example uses lazy collections to efficiently paginate through a large dataset of products, caching each page for an hour.

4. Event-Driven Cache Invalidation

To keep your cache in sync with your database, you can use Laravel’s model events to automatically invalidate relevant caches when data changes.

Example: Auto-Invalidating Product Caches

use App\Models\Product;
use Illuminate\Support\Facades\Cache;
class ProductObserver
{
public function saved(Product $product)
{
Cache::forget("product_{$product->id}");
Cache::tags(['products'])->flush();
}
public function deleted(Product $product)
{
Cache::forget("product_{$product->id}");
Cache::tags(['products'])->flush();
}
}
// In your AppServiceProvider
public function boot()
{
Product::observe(ProductObserver::class);
}

This observer automatically clears product-specific caches and tagged caches whenever a product is saved or deleted.

Best Practices and Tips

  • Use appropriate cache durations: Balance between cache freshness and performance. Longer durations improve performance but may serve stale data.
  • Implement cache warming: For critical data, implement a cache warming mechanism that pre-populates the cache during off-peak hours.
  • Monitor cache usage: Use Laravel’s cache events to log and monitor cache hits and misses, helping you optimize your caching strategy.
  • Use cache prefixes: When working in shared hosting environments, use cache prefixes to avoid conflicts with other applications.
  • Implement fallback mechanisms: Always have a fallback mechanism in case the cache fails or becomes corrupted.
  • Be mindful of cache size: Large cached items can consume significant memory. Consider compressing large items or using alternative storage methods for very large datasets.

Conclusion

Caching is a powerful tool in the Laravel developer’s arsenal, capable of dramatically improving application performance when used correctly. By understanding the various caching techniques and applying them to real-world scenarios, you can create lightning-fast applications that can handle high traffic and complex data operations with ease.

Remember, effective caching is about finding the right balance between performance and data freshness. Always profile your application to identify bottlenecks and apply caching strategically where it provides the most benefit.

As you continue to work with Laravel 11’s caching system, experiment with different techniques and don’t be afraid to combine multiple caching strategies to achieve optimal performance for your specific use case. Happy caching!

Article Tags:

  • Laravel 11
  • Caching
  • Performance Optimization
  • Database Caching
  • API Caching
  • Fragment Caching
  • Cache Tags
  • Cache Locks
  • Lazy Collections
  • Event-Driven Caching
  • Web Development
  • PHP

--

--

Abu Sayed
Abu Sayed

Written by Abu Sayed

Bangladeshi Full Stack Web Dev, Sys Admin & DevOps Engineer. Skills: Data analysis, SQL, Unity, C#. Python, PHP & Laravel. Me on: bd.linkedin.com/in/imabusayed

No responses yet