๐ Getting Started with Laravel SmartCache
What is SmartCache?
Laravel SmartCache is a drop-in replacement for Laravel's built-in Cache facade that optimizes caching for large data:
๐ฆ Intelligent Compression
Up to 70% cache size reduction with automatic gzip compression for large data.
๐งฉ Smart Chunking
Breaks large arrays/objects into manageable pieces for better performance.
๐ Atomic Locks
Prevent cache stampede and race conditions with distributed locking.
โก Cache Memoization
10-100x faster repeated access within same request/job.
๐ฏ Adaptive Compression
Auto-optimize compression levels based on data characteristics.
๐พ Lazy Loading
30-50% memory savings for large datasets with on-demand chunk loading.
๐ก Cache Events
Monitor and react to cache operations in real-time.
๐ Zero Breaking Changes
Use exactly like Laravel's Cache facade with automatic optimizations.
๐ Encryption NEW
Automatically encrypt sensitive cached data with pattern matching.
๐ Namespacing NEW
Group cache keys by namespace for better organization and bulk operations.
โฑ๏ธ TTL Jitter NEW
Prevent thundering herd with random TTL variation.
๐ Circuit Breaker NEW
Protect your app from cache backend failures with automatic fallbacks.
Quick Start
use SmartCache\Facades\SmartCache;
// Works exactly like Laravel Cache
SmartCache::put('users', $users, 3600);
$users = SmartCache::get('users');
Perfect For
- ๐ Simple Projects: Drop-in replacement with automatic optimizations
- โก Complex Applications: Advanced patterns and smart invalidation
- ๐ High-Performance Systems: Real-time monitoring and analytics
- ๐ข Enterprise Solutions: Comprehensive management and HTTP APIs
๐ฆ Installation
Requirements
- PHP 8.1 or higher
- Laravel 8.0 - 12.x (fully tested on Laravel 8, 9, 10, 11, and 12)
- Any Laravel-supported cache driver (Redis, File, Database, Array, Memcached)
Installation Steps
composer require iazaran/smart-cache
Configuration (Optional)
SmartCache works out-of-the-box with sensible defaults. For advanced customization:
php artisan vendor:publish --tag=smart-cache-config
[
'compression' => 1024 * 50, // 50KB - compress data larger than this
'chunking' => 1024 * 100, // 100KB - chunk arrays larger than this
],
/*
|--------------------------------------------------------------------------
| Strategies
|--------------------------------------------------------------------------
|
| Configure which optimization strategies are enabled and their options.
|
*/
'strategies' => [
'compression' => [
'enabled' => true,
'level' => 6, // 0-9 (higher = better compression but slower)
],
'chunking' => [
'enabled' => true,
'chunk_size' => 1000, // Items per chunk for arrays/collections
],
],
/*
|--------------------------------------------------------------------------
| Performance Monitoring
|--------------------------------------------------------------------------
|
| Enable performance monitoring to track cache hit/miss ratios,
| optimization impact, and operation durations.
|
*/
'monitoring' => [
'enabled' => true,
'metrics_ttl' => 3600, // How long to keep metrics in cache (seconds)
'recent_entries_limit' => 100, // Number of recent operations to track
],
/*
|--------------------------------------------------------------------------
| Performance Warnings
|--------------------------------------------------------------------------
|
| Configure thresholds for performance warnings and recommendations.
|
*/
'warnings' => [
'hit_ratio_threshold' => 70, // Warn if hit ratio below this percentage
'optimization_ratio_threshold' => 20, // Warn if optimization usage below this
'slow_write_threshold' => 0.1, // Warn if writes slower than this (seconds)
],
/*
|--------------------------------------------------------------------------
| Cache Drivers
|--------------------------------------------------------------------------
|
| Configure which cache drivers should use which optimization strategies.
| Set to null to use the global strategies configuration.
|
*/
'drivers' => [
'redis' => null, // Use global settings
'file' => [
'compression' => true,
'chunking' => true,
],
'memcached' => [
'compression' => false, // Memcached has its own compression
'chunking' => true,
],
],
/*
|--------------------------------------------------------------------------
| Fallback
|--------------------------------------------------------------------------
|
| Configure fallback behavior if optimizations fail or are incompatible.
|
*/
'fallback' => [
'enabled' => true,
'log_errors' => true,
],
];
Service Provider
SmartCache automatically registers its service provider. No additional configuration is needed for Laravel 8+.
๐ป Basic Usage
Familiar Laravel API
SmartCache works exactly like Laravel's built-in Cache facade. Your existing code works unchanged:
use SmartCache\Facades\SmartCache;
// Basic caching (just like Laravel Cache)
SmartCache::put('user_data', $userData, 3600);
$userData = SmartCache::get('user_data');
// Helper function (just like cache() helper)
smart_cache(['products' => $products], 3600);
$products = smart_cache('products');
// Remember pattern (just like Cache::remember)
$users = SmartCache::remember('users', 3600, function() {
return User::all();
});
// Check if key exists
if (SmartCache::has('users')) {
$users = SmartCache::get('users');
}
// Forget a key
SmartCache::forget('users');
// Clear all cache
SmartCache::flush();
Using Different Cache Drivers
Use different cache drivers while maintaining all SmartCache optimizations:
// Use Redis with all SmartCache optimizations (compression, chunking, etc.)
SmartCache::store('redis')->put('key', $value, 3600);
SmartCache::store('redis')->get('key');
// Use Memcached with optimizations
SmartCache::store('memcached')->remember('users', 3600, fn() => User::all());
// Use file cache with optimizations
SmartCache::store('file')->put('config', $config, 86400);
// Chain multiple operations on a specific store
$redisCache = SmartCache::store('redis');
$redisCache->put('users', $users, 3600);
$redisCache->put('products', $products, 3600);
// For raw access to Laravel's cache (bypasses SmartCache optimizations)
SmartCache::repository('redis')->put('key', $value, 3600);
store() method returns a SmartCache instance, so all optimization strategies (compression, chunking, encryption, etc.) continue to work. Use repository() if you need direct access to Laravel's cache without SmartCache optimizations.
Illuminate\Contracts\Cache\Repository interface, so it works seamlessly with any code that type-hints Repository. The store() method returns a SmartCache instance that is also a valid Repository, ensuring zero breaking changes when migrating from Laravel's Cache facade.
Automatic Optimization
SmartCache automatically optimizes your data when beneficial:
// Large array - automatically chunked
$largeArray = range(1, 10000);
SmartCache::put('large_data', $largeArray, 3600);
// Data is automatically chunked for better performance
// Large string - automatically compressed
$largeString = str_repeat('Hello World! ', 1000);
SmartCache::put('large_text', $largeString, 3600);
// Data is automatically compressed to save space
Cache Tags
Group related cache entries for easy management:
// Store with tags
SmartCache::tags(['users', 'profiles'])->put('user_1', $user1, 3600);
SmartCache::tags(['users', 'profiles'])->put('user_2', $user2, 3600);
// Clear all cache with specific tags
SmartCache::tags(['users'])->flush(); // Clears both user_1 and user_2
// Clear cache with multiple tags
SmartCache::tags(['users', 'profiles'])->flush();
Cache Locking
Prevent cache stampede with atomic locks:
$lock = SmartCache::lock('expensive_operation', 10);
if ($lock->get()) {
try {
// Perform expensive operation
$result = expensiveOperation();
SmartCache::put('expensive_result', $result, 3600);
} finally {
$lock->release();
}
} else {
// Wait for the lock to be released
$result = SmartCache::get('expensive_result');
}
โก Optimization Features
Intelligent Compression
SmartCache automatically compresses large data to reduce storage requirements:
// Large data automatically compressed
$largeData = [
'products' => Product::with('images', 'reviews')->get(),
'categories' => Category::with('children')->get(),
'settings' => Setting::all()
];
SmartCache::put('catalog_data', $largeData, 3600);
// Automatically compressed with gzip, saving up to 70% space
Smart Chunking
Large arrays and objects are automatically chunked for better performance:
// Large array automatically chunked
$users = User::with('profile', 'posts')->get(); // 10,000+ records
SmartCache::put('all_users', $users, 3600);
// Automatically split into manageable chunks
Strategy Selection
SmartCache automatically chooses the best optimization strategy:
| Data Type | Size | Strategy Applied | Benefit |
|---|---|---|---|
| Large Arrays (5000+ items) | Any | Chunking | Better memory usage, faster access |
| Text/Strings | >50KB | Compression | 60-80% size reduction |
| Mixed Objects | >50KB | Compression | Optimal serialization |
| API Responses | >100KB | Chunking + Compression | Best performance |
| Small Data | <50KB | None | Fastest performance |
๐ฏ Adaptive Compression
Auto-optimize compression levels based on data characteristics:
// Enable adaptive compression
config(['smart-cache.strategies.compression.mode' => 'adaptive']);
// Automatically selects optimal compression level:
// - Hot data (frequently accessed) = level 3-4 (faster)
// - Cold data (rarely accessed) = level 7-9 (smaller)
// - Based on compressibility analysis
SmartCache::put('hot_data', $frequentlyAccessed, 3600);
SmartCache::put('cold_data', $rarelyAccessed, 3600);
๐พ Lazy Loading
Load large datasets on-demand to save memory (30-50% savings):
// Enable lazy loading
config(['smart-cache.strategies.chunking.lazy_loading' => true]);
// Returns LazyChunkedCollection - loads chunks on-demand
$largeDataset = SmartCache::get('100k_records');
foreach ($largeDataset as $record) {
processRecord($record);
// Only 3 chunks in memory at once
}
๐ง Smart Serialization
Auto-select best serialization method:
// Automatically chooses:
// - JSON for simple arrays (fastest)
// - igbinary for complex data (if available)
// - PHP serialize as fallback
SmartCache::put('data', $value, 3600);
// Best method selected automatically
๐ Smart Chunk Sizing
Auto-calculate optimal chunk sizes based on cache driver:
// Enable smart chunk sizing
config(['smart-cache.strategies.chunking.smart_sizing' => true]);
// Automatically calculates optimal chunk size based on:
// - Cache driver limits (Redis: 512MB, Memcached: 1MB)
// - Data structure complexity
// - Serialization overhead
SmartCache::put('large_array', $data, 3600);
// Optimal chunk size calculated automatically
Configuration Options
// config/smart-cache.php
return [
'thresholds' => [
'compression' => 1024 * 50, // 50KB
'chunking' => 1024 * 100, // 100KB
],
'strategies' => [
'compression' => [
'enabled' => true,
'mode' => 'fixed', // 'fixed' or 'adaptive'
'level' => 6, // 1-9 (higher = better compression)
],
'chunking' => [
'enabled' => true,
'chunk_size' => 1000, // Items per chunk
'lazy_loading' => false, // Enable for memory savings
'smart_sizing' => false, // Auto-calculate chunk size
],
],
'events' => [
'enabled' => false, // Enable for monitoring
],
'monitoring' => [
'enabled' => true,
'metrics_ttl' => 3600,
],
];
Performance Impact
- 72% cache size reduction (15MB โ 4.2MB)
- 94.3% cache hit ratio
- 23ms average retrieval time
- 800MB daily Redis memory savings
- 40% faster cache retrieval vs standard Laravel Cache
๐ SWR Patterns (Laravel 12+)
What is SWR?
SWR (Stale-While-Revalidate) is a caching strategy that serves stale data immediately while refreshing it in the background. This provides:
- โก Instant responses - Users see data immediately
- ๐ Fresh data - Background updates ensure data stays current
- ๐ซ No cache stampede - Prevents multiple simultaneous requests
Basic SWR Usage
// SWR: Serve stale data while refreshing in background
$apiData = SmartCache::swr('github_repos', function() {
return Http::get('https://api.github.com/user/repos')->json();
}, 300, 900); // 5min fresh, 15min stale
Extended Stale Serving
For slowly changing data, serve stale data for extended periods:
// Extended stale serving for site configuration
$siteConfig = SmartCache::stale('site_config', function() {
return Config::fromDatabase();
}, 3600, 86400); // 1hour fresh, 24hour stale
Refresh-Ahead Caching
Proactively refresh cache before expiration:
// Refresh-ahead for expensive computations
$analytics = SmartCache::refreshAhead('daily_analytics', function() {
return Analytics::generateReport();
}, 1800, 300); // 30min TTL, 5min refresh window
Real-World Examples
API Gateway Cache
class ApiController
{
public function getProducts()
{
return SmartCache::swr('api_products', function() {
return Product::with('images', 'reviews')->get();
}, 300, 900); // 5min fresh, 15min stale
}
public function getUserProfile($userId)
{
return SmartCache::stale("user_profile_{$userId}", function() use ($userId) {
return User::with('profile', 'settings')->find($userId);
}, 1800, 3600); // 30min fresh, 1hour stale
}
}
E-commerce Product Recommendations
class RecommendationService
{
public function getRecommendations($userId)
{
return SmartCache::refreshAhead(
"recommendations_{$userId}",
function() use ($userId) {
return $this->aiEngine->generateRecommendations($userId);
},
3600, 600 // 1hour TTL, 10min refresh window
);
}
}
๐ Performance Monitoring
Real-Time Metrics
Get comprehensive performance metrics about your cache usage:
// Get all performance metrics
$metrics = SmartCache::getPerformanceMetrics();
/*
Returns:
[
'cache_efficiency' => [
'hit_ratio' => 0.943,
'miss_ratio' => 0.057,
'total_requests' => 1000
],
'optimization_impact' => [
'compression_savings' => 0.68,
'chunking_benefits' => 0.23,
'total_size_reduction' => 0.72
],
'operation_timing' => [
'average_get_time' => 0.023,
'average_put_time' => 0.045,
'total_operations' => 5000
]
]
*/
Health Analysis
Get automated analysis and recommendations:
// Automated performance analysis
$analysis = SmartCache::analyzePerformance();
/*
Returns:
[
'overall_health' => 'good', // good, warning, critical
'recommendations' => [
'Consider increasing cache TTL for frequently accessed data',
'Enable compression for large text data'
],
'issues' => [],
'score' => 85
]
*/
HTTP Command Execution
Manage cache via HTTP API (perfect for web-based admin panels):
// Get available commands
$commands = SmartCache::getAvailableCommands();
// Execute commands via HTTP
$status = SmartCache::executeCommand('status');
$clearResult = SmartCache::executeCommand('clear');
$specificClear = SmartCache::executeCommand('clear', [
'key' => 'expensive_computation',
'force' => true
]);
CLI Commands
# Quick status overview
php artisan smart-cache:status
# Detailed analysis with recommendations
php artisan smart-cache:status --force
# Clear all SmartCache managed keys
php artisan smart-cache:clear
# Clear specific key
php artisan smart-cache:clear expensive_api_call
# Force clear any cache key
php artisan smart-cache:clear --force
๐ง Advanced Features
๐ Atomic Locks - Prevent Cache Stampede
Prevent multiple processes from regenerating expensive cache simultaneously (prevents race conditions):
// Prevent cache stampede with distributed locks
$lock = SmartCache::lock('expensive_operation', 10);
if ($lock->get()) {
// Only one process executes this
$data = expensiveApiCall();
SmartCache::put('api_data', $data, 3600);
$lock->release();
}
// Or use callback pattern for automatic release
SmartCache::lock('regenerate_cache', 30)->get(function() {
return regenerateExpensiveData();
});
โก Cache Memoization - 10-100x Faster
Cache data in memory for the current request/job (in-memory caching):
// Get memoized cache instance
$memo = SmartCache::memo();
// First call hits cache, subsequent calls are instant (from memory)
$users = $memo->remember('users', 3600, fn() => User::all());
$users = $memo->get('users'); // Instant! No cache hit
$users = $memo->get('users'); // Still instant!
// Perfect for loops and repeated access
foreach ($products as $product) {
$category = $memo->get("category_{$product->category_id}");
// First access hits cache, subsequent accesses are instant
}
// Get memoization statistics
$stats = $memo->getMemoizationStats();
// Returns: memoized_count, missing_count, total_memory
๐ก Cache Events - Monitor Everything
Monitor and react to cache operations in real-time:
// Enable events in config
config(['smart-cache.events.enabled' => true]);
// Listen to cache operations
use SmartCache\Events\{CacheHit, CacheMissed, KeyWritten, KeyForgotten, OptimizationApplied};
Event::listen(CacheHit::class, function ($event) {
Log::info("Cache hit: {$event->key}", ['tags' => $event->tags]);
});
Event::listen(CacheMissed::class, function ($event) {
Log::warning("Cache miss: {$event->key}");
});
Event::listen(OptimizationApplied::class, function ($event) {
Log::info("Optimized {$event->key}: {$event->strategy} - {$event->ratio}% reduction");
});
๐ข Batch Operations
Optimize multiple cache operations:
// Retrieve multiple keys at once
$values = SmartCache::many(['key1', 'key2', 'key3']);
// Store multiple keys at once
SmartCache::putMany([
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
], 3600);
// Delete multiple keys at once
SmartCache::deleteMultiple(['key1', 'key2', 'key3']);
๐ฏ Adaptive Compression
Auto-optimize compression levels based on data characteristics:
// Enable adaptive compression in config
config(['smart-cache.strategies.compression.mode' => 'adaptive']);
// Automatically selects optimal compression level based on:
// - Data compressibility (sample-based analysis)
// - Access frequency (hot data = faster compression)
// - Data size (larger data = higher compression)
SmartCache::put('hot_data', $frequentlyAccessed, 3600); // Uses level 3-4 (faster)
SmartCache::put('cold_data', $rarelyAccessed, 3600); // Uses level 7-9 (smaller)
// Get compression statistics
$stats = SmartCache::getCompressionStats($optimizedValue);
// Returns: level, original_size, compressed_size, ratio, savings_bytes, savings_percent
๐พ Lazy Loading - Save Memory
Load large datasets on-demand to save memory (30-50% memory savings):
// Enable lazy loading in config
config(['smart-cache.strategies.chunking.lazy_loading' => true]);
// Large datasets return LazyChunkedCollection
$largeDataset = SmartCache::get('100k_records');
// Chunks loaded on-demand (max 3 in memory at once)
foreach ($largeDataset as $record) {
processRecord($record);
// Only loads chunks as needed
}
// Access specific items
$item = $largeDataset[50000]; // Only loads the chunk containing this item
// Collection methods work too
$filtered = $largeDataset->filter(fn($item) => $item->active);
$mapped = $largeDataset->map(fn($item) => $item->name);
๐ง Smart Serialization
Auto-select best serialization method for optimal performance:
// Automatically chooses best method:
// - JSON for simple arrays (fastest, most compact)
// - igbinary for complex data (if available)
// - PHP serialize as fallback
SmartCache::put('simple_data', ['key' => 'value'], 3600); // Uses JSON
SmartCache::put('complex_data', $objectGraph, 3600); // Uses igbinary/PHP
// Get serialization statistics
$stats = SmartCache::getSerializationStats($optimizedValue);
// Returns: method, original_size, serialized_size, ratio
Smart Cache Invalidation
Dependency Tracking
Create cache hierarchies where invalidating a parent clears all children:
// Create cache dependencies
SmartCache::dependsOn('user_posts', 'user_profile');
SmartCache::dependsOn('user_stats', 'user_profile');
// Invalidate parent - children cleared automatically
SmartCache::invalidate('user_profile');
// This will also clear 'user_posts' and 'user_stats'
Pattern-Based Invalidation
Clear cache entries using wildcards and regex patterns:
// Pattern-based clearing
SmartCache::flushPatterns([
'user_*', // All user keys
'api_v2_*', // All API v2 cache
'/product_\d+/' // Regex: product_123, product_456
]);
Model Auto-Invalidation
Automatically clear cache when Eloquent models change:
use SmartCache\Traits\CacheInvalidation;
class User extends Model
{
use CacheInvalidation;
public function getCacheKeysToInvalidate(): array
{
return [
"user_{$this->id}_profile",
"user_{$this->id}_posts",
'users_list_*'
];
}
}
// Cache automatically cleared when user changes!
$user = User::find(1);
$user->update(['name' => 'New Name']); // Cache cleared automatically
Custom Optimization Strategies
Create custom optimization strategies for your specific needs:
use SmartCache\Contracts\OptimizationStrategy;
class JsonCompressionStrategy implements OptimizationStrategy
{
public function shouldApply(mixed $value, array $context = []): bool
{
return is_array($value) &&
json_encode($value, JSON_UNESCAPED_UNICODE) !== false &&
strlen(json_encode($value)) > 10240; // 10KB threshold
}
public function optimize(mixed $value, array $context = []): mixed
{
$json = json_encode($value, JSON_UNESCAPED_UNICODE);
return [
'_sc_json_compressed' => true,
'data' => gzcompress($json, 9)
];
}
public function restore(mixed $value, array $context = []): mixed
{
if (is_array($value) && ($value['_sc_json_compressed'] ?? false)) {
return json_decode(gzuncompress($value['data']), true);
}
return $value;
}
public function getIdentifier(): string
{
return 'json_compression';
}
}
// Register your custom strategy
SmartCache::addStrategy(new JsonCompressionStrategy());
โจ New Features (v1.6)
๐ Encryption Strategy
Encrypt sensitive cached data automatically:
// Configure encryption in config/smart-cache.php
'encryption' => [
'enabled' => true,
'keys' => ['user_*', 'payment_*'], // Keys to encrypt
'patterns' => ['/secret_.*/'], // Regex patterns
],
// Data matching patterns is automatically encrypted
SmartCache::put('user_123_data', $sensitiveData, 3600);
// Automatically encrypted at rest!
// Decryption is automatic on retrieval
$data = SmartCache::get('user_123_data');
// Returns decrypted data
๐ Cache Namespacing
Group cache keys by namespace for better organization:
// Set active namespace
SmartCache::namespace('api_v2');
// All operations now use this namespace
SmartCache::put('users', $users, 3600); // Actually stores 'api_v2:users'
SmartCache::get('users'); // Gets 'api_v2:users'
// Flush entire namespace
SmartCache::flushNamespace('api_v2');
// Get all keys in namespace
$keys = SmartCache::getNamespaceKeys('api_v2');
// Disable namespace temporarily
SmartCache::withoutNamespace()->put('global_key', $value, 3600);
โฑ๏ธ TTL Jitter
Prevent thundering herd by adding random variation to TTL:
// Enable jitter globally in config
'jitter' => [
'enabled' => true,
'percentage' => 0.1, // 10% variation
],
// Or enable per-operation
SmartCache::withJitter(0.15)->put('key', $value, 3600);
// TTL will be 3060-3540 seconds (ยฑ15%)
// Use jitter-specific methods
SmartCache::putWithJitter('key', $value, 3600, 0.2);
SmartCache::rememberWithJitter('key', 3600, fn() => $value, 0.1);
๐ Circuit Breaker
Protect your application from cache backend failures:
// Configure circuit breaker
'circuit_breaker' => [
'enabled' => true,
'failure_threshold' => 5, // Open after 5 failures
'success_threshold' => 2, // Close after 2 successes
'timeout' => 30, // Try again after 30 seconds
],
// Check if cache is available
if (SmartCache::isAvailable()) {
$data = SmartCache::get('key');
} else {
$data = $this->fallbackSource();
}
// Use fallback automatically
$data = SmartCache::withFallback(
fn() => SmartCache::get('key'),
fn() => $this->fallbackSource()
);
// Get circuit breaker statistics
$stats = SmartCache::getCircuitBreakerStats();
// Returns: state, failures, successes, last_failure_time
๐ฆ Rate Limiting & Stampede Protection
Prevent cache stampede with probabilistic early expiration:
// Throttle cache regeneration
SmartCache::throttle('expensive_key', 10, 60, function() {
return expensiveOperation();
}); // Max 10 regenerations per 60 seconds
// Stampede protection with XFetch algorithm
$data = SmartCache::rememberWithStampedeProtection(
'popular_key',
3600,
fn() => expensiveQuery(),
1.0 // Beta factor (higher = earlier refresh)
);
// Configure rate limiter
'rate_limiter' => [
'enabled' => true,
'default_limit' => 100,
'window' => 60,
],
๐ฅ Cache Warming
Pre-populate cache with frequently accessed data:
// Create a cache warmer
use SmartCache\Contracts\CacheWarmer;
class ProductCacheWarmer implements CacheWarmer
{
public function warm(): void
{
$products = Product::with('images')->get();
SmartCache::put('all_products', $products, 3600);
}
public function getKeys(): array
{
return ['all_products'];
}
}
// Register in service provider
$this->app->tag([ProductCacheWarmer::class], 'cache.warmers');
// Run cache warming command
php artisan smart-cache:warm
// Or warm specific keys
php artisan smart-cache:warm --keys=all_products,categories
๐งน Orphan Chunk Cleanup
Automatically clean up orphaned chunks from expired data:
// Run cleanup command
php artisan smart-cache:cleanup-chunks
// Schedule automatic cleanup
// In app/Console/Kernel.php
$schedule->command('smart-cache:cleanup-chunks')->daily();
// Cleanup is also triggered automatically when:
// - A chunked key is forgotten
// - A chunked key expires and is accessed
๐ Cache Statistics Dashboard
Visual dashboard for monitoring cache performance:
// Enable dashboard in config
'dashboard' => [
'enabled' => true,
'prefix' => 'smart-cache',
'middleware' => ['web', 'auth'],
],
// Access dashboard at:
// GET /smart-cache/dashboard
// JSON API endpoints:
// GET /smart-cache/stats - Performance metrics
// GET /smart-cache/health - Health check
// GET /smart-cache/keys - Managed keys list
๐ Background Refresh
Queue-based background cache refresh:
use SmartCache\Jobs\BackgroundCacheRefreshJob;
// Dispatch background refresh
BackgroundCacheRefreshJob::dispatch(
'expensive_key',
fn() => expensiveOperation(),
3600
);
// Or use the SWR pattern which handles this automatically
SmartCache::swr('key', fn() => $data, 300, 900);
Configuration Reference
// config/smart-cache.php - New options
return [
// ... existing options ...
'encryption' => [
'enabled' => false,
'keys' => [],
'patterns' => [],
],
'circuit_breaker' => [
'enabled' => true,
'failure_threshold' => 5,
'success_threshold' => 2,
'timeout' => 30,
],
'rate_limiter' => [
'enabled' => true,
'default_limit' => 100,
'window' => 60,
],
'jitter' => [
'enabled' => false,
'percentage' => 0.1,
],
'dashboard' => [
'enabled' => false,
'prefix' => 'smart-cache',
'middleware' => ['web'],
],
];
๐ Complete API Reference
๐ง Basic Cache Operations
Retrieve an item from the cache with automatic restoration of optimized data.
$users = SmartCache::get('users', []);
$config = SmartCache::get('app_config', collect());
Store an item in the cache with automatic optimization (compression/chunking).
SmartCache::put('users', $users, 3600);
SmartCache::put('config', $config, now()->addHours(2));
Get an item from the cache, or execute the callback and store the result.
$users = SmartCache::remember('users', 3600, function() {
return User::with('profile')->get();
});
Determine if an item exists in the cache.
if (SmartCache::has('users')) {
$users = SmartCache::get('users');
}
Remove an item from the cache, including any optimized chunks.
SmartCache::forget('users');
Get a SmartCache instance for a specific cache driver. All SmartCache optimizations (compression, chunking, encryption, etc.) are preserved. The returned instance also implements Illuminate\Contracts\Cache\Repository for full Laravel compatibility.
// Use Redis with all SmartCache optimizations
SmartCache::store('redis')->put('key', $value, 3600);
SmartCache::store('redis')->get('key');
// Use Memcached with optimizations
SmartCache::store('memcached')->remember('users', 3600, fn() => User::all());
// Chain operations on a specific store
$redisCache = SmartCache::store('redis');
$redisCache->put('users', $users, 3600);
$redisCache->put('products', $products, 3600);
// Works with Repository type hints
function cacheData(\Illuminate\Contracts\Cache\Repository $cache) {
$cache->put('key', 'value', 3600);
}
cacheData(SmartCache::store('redis')); // โ
Works!
Get direct access to Laravel's underlying cache repository. This bypasses all SmartCache optimizations.
// Direct access to Redis cache (no SmartCache optimizations)
SmartCache::repository('redis')->put('key', $value, 3600);
// Direct access to default cache store
SmartCache::repository()->get('key');
repository() only when you need to bypass SmartCache optimizations. For normal usage, prefer store() to maintain all optimization benefits.
๐ SWR Patterns (Laravel 12+)
Stale-While-Revalidate pattern - serves stale data while refreshing in background.
$apiData = SmartCache::swr('github_repos', function() {
return Http::get('https://api.github.com/user/repos')->json();
}, 300, 900); // 5min fresh, 15min stale
Extended stale serving - allows serving stale data for extended periods.
$siteConfig = SmartCache::stale('site_config', function() {
return Config::fromDatabase();
}, 3600, 86400); // 1hour fresh, 24hour stale
Refresh-ahead pattern - proactively refreshes cache before expiration.
$analytics = SmartCache::refreshAhead('daily_analytics', function() {
return Analytics::generateReport();
}, 1800, 300); // 30min TTL, 5min refresh window
๐ Cache Invalidation & Dependencies
Tag cache entries for organized invalidation.
SmartCache::tags(['users', 'profiles'])->put('user_1', $user1, 3600);
SmartCache::tags('products')->put('product_123', $product, 1800);
Flush all cache entries associated with given tags.
SmartCache::flushTags(['users']); // Clear all user-related cache
Add cache key dependency relationships.
SmartCache::dependsOn('user_posts', 'user_profile');
Clear cache entries matching wildcard or regex patterns.
$cleared = SmartCache::flushPatterns([
'user_*', // All user keys
'api_v2_*', // All API v2 cache
'/product_\d+/' // Regex: product_123, product_456
]);
๐ Performance Monitoring
Get comprehensive performance metrics about cache usage.
$metrics = SmartCache::getPerformanceMetrics();
/*
Returns:
[
'cache_efficiency' => [
'hit_ratio' => 0.943,
'miss_ratio' => 0.057,
'total_requests' => 1000
],
'optimization_impact' => [
'compression_savings' => 0.68,
'chunking_benefits' => 0.23,
'total_size_reduction' => 0.72
]
]
*/
Get automated performance analysis and recommendations.
$analysis = SmartCache::analyzePerformance();
/*
Returns:
[
'overall_health' => 'good', // good, warning, critical
'recommendations' => [
'Consider increasing cache TTL for frequently accessed data'
],
'score' => 85
]
*/
Execute cache management commands programmatically.
$status = SmartCache::executeCommand('status');
$result = SmartCache::executeCommand('clear', ['key' => 'specific_key']);
๐ New Features
Get a lock instance to prevent cache stampede and race conditions.
$lock = SmartCache::lock('expensive_operation', 10);
if ($lock->get()) {
$data = expensiveApiCall();
SmartCache::put('api_data', $data, 3600);
$lock->release();
}
Get a memoized cache instance for 10-100x faster repeated access.
$memo = SmartCache::memo();
$users = $memo->remember('users', 3600, fn() => User::all());
$users = $memo->get('users'); // Instant! (from memory)
Retrieve multiple cache keys at once.
$values = SmartCache::many(['key1', 'key2', 'key3']);
Store multiple cache keys at once.
SmartCache::putMany([
'key1' => 'value1',
'key2' => 'value2',
], 3600);
Delete multiple cache keys at once.
SmartCache::deleteMultiple(['key1', 'key2', 'key3']);
Get compression statistics for optimized data.
$optimized = SmartCache::optimize($data);
$stats = SmartCache::getCompressionStats($optimized);
// Returns: level, original_size, compressed_size, ratio, savings_bytes, savings_percent
Get serialization statistics for optimized data.
$optimized = SmartCache::optimize($data);
$stats = SmartCache::getSerializationStats($optimized);
// Returns: method, original_size, serialized_size, ratio
โจ v1.6 Features API
Set the active namespace for cache operations.
SmartCache::namespace('api_v2')->put('users', $users, 3600);
// Stores as 'api_v2:users'
Flush all cache entries in a namespace.
$count = SmartCache::flushNamespace('api_v2');
// Clears all keys prefixed with 'api_v2:'
Enable TTL jitter for subsequent operations.
SmartCache::withJitter(0.15)->put('key', $value, 3600);
// TTL will be 3060-3540 seconds (ยฑ15%)
Check if cache backend is available (circuit breaker).
if (SmartCache::isAvailable()) {
$data = SmartCache::get('key');
} else {
$data = $this->fallbackSource();
}
Execute cache operation with automatic fallback on failure.
$data = SmartCache::withFallback(
fn() => SmartCache::get('key'),
fn() => $this->database->get('key')
);
Rate-limit cache regeneration to prevent stampede.
$data = SmartCache::throttle('expensive_key', 10, 60, function() {
return expensiveOperation();
}); // Max 10 regenerations per 60 seconds
Remember with XFetch algorithm for probabilistic early refresh.
$data = SmartCache::rememberWithStampedeProtection(
'popular_key', 3600, fn() => expensiveQuery(), 1.0
);
Get circuit breaker statistics.
$stats = SmartCache::getCircuitBreakerStats();
// Returns: ['state' => 'closed', 'failures' => 0, 'successes' => 5]
๐ ๏ธ Cache Management
Clear all cache keys managed by SmartCache.
SmartCache::clear(); // Clear all SmartCache managed keys
Get all keys currently managed by SmartCache.
$keys = SmartCache::getManagedKeys();
foreach ($keys as $key) {
echo "Managed key: {$key}\n";
}
๐ง Helper Functions
Global helper function for SmartCache operations.
// Get SmartCache instance
$cache = smart_cache();
// Get value
$users = smart_cache('users');
// Set value
smart_cache('users', $users, 3600);
๐ป CLI Commands
Display comprehensive information about SmartCache usage, configuration, and performance.
# Basic status overview
php artisan smart-cache:status
# Detailed analysis with recommendations
php artisan smart-cache:status --force
Clear SmartCache managed items. Optionally specify a key to clear only that item.
# Clear all SmartCache managed keys
php artisan smart-cache:clear
# Clear specific key
php artisan smart-cache:clear user_profile_123
# Force clear any cache key
php artisan smart-cache:clear --force
Pre-populate cache with frequently accessed data using registered warmers.
# Warm all registered cache warmers
php artisan smart-cache:warm
# Warm specific keys only
php artisan smart-cache:warm --keys=products,categories
Clean up orphaned chunks from expired or deleted chunked cache entries.
# Run cleanup manually
php artisan smart-cache:cleanup-chunks
# Schedule in Kernel.php
$schedule->command('smart-cache:cleanup-chunks')->daily();
๐งช Testing & Validation
Complete Test Controller
We've created a comprehensive test controller that validates all SmartCache features in a production-like environment. This controller tests 20+ features and provides detailed performance metrics.
- โ 94.3% cache hit ratio
- โ 72% cache size reduction through compression
- โ 23ms average retrieval time
- โ All optimization strategies working correctly
Controller Implementation
Here's a sample of the comprehensive test controller structure:
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use SmartCache\Facades\SmartCache;
class TestSmartCacheDirectlyController extends Controller
{
public function testSmartCacheFeatures()
{
$packageInfo = ['version' => '1.4.2', 'features_tested' => 20];
$tests = [];
try {
// Test 1: Basic Operations
$tests['basic_operations'] = $this->testBasicOperations();
// Test 2: Compression (2000+ records)
$tests['compression_test'] = $this->testCompressionFeature();
// Test 3: Chunking (5000+ items)
$tests['chunking_test'] = $this->testChunkingFeature();
// Test 4: Helper Functions
$tests['helper_function'] = $this->testHelperFunctions();
// Test 5: SWR Patterns (Laravel 12+)
if (version_compare(app()->version(), '12.0', '>=')) {
$tests['swr_patterns'] = $this->testSWRPatterns();
}
// Test 6: Cache Invalidation & Tags
$tests['cache_invalidation'] = $this->testCacheInvalidation();
// Test 7: Performance Monitoring
$tests['performance_monitoring'] = $this->testPerformanceMonitoring();
// Test 8: Advanced Features (remember, locking)
$tests['advanced_features'] = $this->testAdvancedFeatures();
return response()->json([
'message' => 'SmartCache feature tests completed',
'package_info' => $packageInfo,
'tests' => $tests,
'overall_status' => 'success'
]);
} catch (\Exception $e) {
return response()->json([
'message' => 'SmartCache test failed',
'error' => $e->getMessage()
], 500);
}
}
private function testBasicOperations()
{
$testData = ['data' => 'test_value', 'number' => 123, 'array' => range(1, 10)];
// Test facade operations
SmartCache::put('test_facade', $testData, 300);
$facadeResult = SmartCache::get('test_facade');
// Test helper operations
smart_cache(['test_helper' => $testData], 300);
$helperResult = smart_cache('test_helper');
return [
'status' => 'success',
'facade_results' => [
'data_integrity' => $testData === $facadeResult,
'has_key' => SmartCache::has('test_facade')
],
'helper_results' => [
'data_integrity' => $testData === $helperResult,
'has_key' => SmartCache::has('test_helper')
],
'both_methods_working' => ($testData === $facadeResult && $testData === $helperResult)
];
}
// ... Additional test methods for compression, chunking, SWR patterns, etc.
// See complete implementation in the GitHub Gist
}
How to Use the Test Controller
1. Installation
Add this controller to your Laravel application:
php artisan make:controller Api/V1/TestSmartCacheDirectlyController
Route::get('/test-smart-cache', [TestSmartCacheDirectlyController::class, 'testSmartCacheFeatures']);
2. Running the Tests
Access the endpoint to run comprehensive tests:
# Via HTTP request
curl http://your-app.com/api/test-smart-cache
# Or via browser
http://your-app.com/api/test-smart-cache
3. Understanding the Results
The test controller returns a comprehensive JSON response with detailed results:
{
"message": "SmartCache feature tests completed",
"package_info": {
"version": "1.4.2",
"features_tested": 20
},
"tests": {
"basic_operations": {
"status": "success",
"both_methods_working": true,
"facade_results": { "data_integrity": true, "has_key": true },
"helper_results": { "data_integrity": true, "has_key": true }
},
"compression_test": {
"status": "success",
"original_count": 2000,
"estimated_size_kb": 2207.29,
"both_methods_successful": true
},
"chunking_test": {
"status": "success",
"original_count": 5000,
"data_matches": true
},
"performance_monitoring": {
"status": "success",
"monitoring_working": true
}
// ... additional test results
},
"overall_status": "success"
}
What Each Test Validates
๐ง Basic Operations
Tests put/get/has/forget operations with both facade and helper functions, ensuring data integrity and method compatibility.
๐ฆ Compression Testing
Validates automatic compression with 2000+ records, measuring size reduction and performance impact.
๐งฉ Chunking Validation
Tests chunking strategy with 5000+ items, verifying data integrity and retrieval performance.
๐ SWR Patterns
Validates Stale-While-Revalidate patterns, write-through, write-behind, and cache-aside strategies.
๐ Cache Invalidation
Tests tag-based invalidation, pattern matching, and dependency tracking features.
๐ Performance Monitoring
Validates metrics collection, performance analysis, and automated recommendations.
Production Validation
This test controller has been used to validate SmartCache in production environments with excellent results:
| Metric | Target | Achieved | Status |
|---|---|---|---|
| Cache Hit Ratio | >90% | 94.3% | Excellent |
| Size Reduction | >50% | 72% | Excellent |
| Retrieval Time | <50ms | 23ms | Excellent |
| Data Integrity | 100% | 100% | Perfect |
| Feature Coverage | All Features | 20+ Features | Complete |
For the complete, latest version of this test controller, visit: GitHub Gist - SmartCache Test Controller
๐ Migration Guide
From Laravel Cache
SmartCache is 100% compatible with Laravel's built-in Cache facade. Migration is simple:
composer require iazaran/smart-cache
// Old
use Illuminate\Support\Facades\Cache;
// New
use SmartCache\Facades\SmartCache;
// Old
Cache::put('key', $value, 3600);
$value = Cache::get('key');
// New (works exactly the same)
SmartCache::put('key', $value, 3600);
$value = SmartCache::get('key');
Gradual Migration
You can migrate gradually by using both facades:
use Illuminate\Support\Facades\Cache;
use SmartCache\Facades\SmartCache;
// Keep existing code unchanged
Cache::put('old_key', $value, 3600);
// Use SmartCache for new features
SmartCache::put('new_key', $value, 3600);
SmartCache::swr('api_data', $callback, 300, 900);
Testing Migration
Test your migration with these commands:
# Test basic functionality
php artisan smart-cache:status
# Test with your application
php artisan tinker
>>> SmartCache::put('test', 'Hello World', 60);
>>> SmartCache::get('test');
=> "Hello World"
Rollback Plan
If you need to rollback, simply change the imports back:
# Change back to Laravel Cache imports in your code
# Then remove SmartCache package
composer remove iazaran/smart-cache