Skip to content

Caching & Performance

Caching and performance packages provide various optimization strategies for different layers of the application.

Filesystem-based cache store using cloud storage (S3, Azure Blob, etc.).

  • Cloud storage as cache backend
  • Hash-based directory sharding
  • Metadata-based TTL tracking
  • Works with any Flysystem adapter

FileStorageCacheServiceProvider extends Laravel’s CacheManager.

config/cache.php
'stores' => [
'file_storage' => [
'driver' => 'file_storage',
'disk' => 's3', // Flysystem disk name
'path_prefix' => 'cache', // Optional prefix
],
],
// Standard cache operations
Cache::store('file_storage')->put('key', $value, 3600);
$value = Cache::store('file_storage')->get('key');
Cache::store('file_storage')->forget('key');
Cache::store('file_storage')->flush();
// Multi-key operations
Cache::store('file_storage')->getMany(['key1', 'key2']);
Cache::store('file_storage')->putMany(['k1' => $v1, 'k2' => $v2], 3600);
  • Path Sharding: 2-level SHA1 sharding ({prefix}/ab/abcd...xyz/)
  • File Extensions: .cache_data and .cache_metadata
  • Unsupported: increment(), decrement(), forever()

Console commands for managing multiple cache layers.

  • Redis cache management
  • APCu cache management
  • Opcache management
  • Tag-based and pattern-based flushing
  • Cache statistics and slowlog analysis
Terminal window
# Redis - flush all
php artisan cache:flush redis --all
# Redis - by tag
php artisan cache:flush redis --tag=users --tag=posts
# Redis - by glob pattern
php artisan cache:flush redis --glob='cache:user:*'
# Redis - by key
php artisan cache:flush redis --key=my_key
# APCu - by regex
php artisan cache:flush apcu --regex='cache:.*:profile'
# Opcache
php artisan cache:flush opcache
# Custom PHP-FPM socket
php artisan cache:flush apcu --socket=/var/run/php/php8.4-fpm.sock
Terminal window
# Redis stats
php artisan cache:stats redis
# Redis slowlog
php artisan cache:stats redis --slowlog=10
# APCu stats
php artisan cache:stats apcu
# Opcache stats
php artisan cache:stats opcache
FilterRedisAPCuOpcache
--all
--tag
--glob
--key
--regex

APCu and Opcache require PHP-FPM socket access since they’re not accessible from CLI:

// Uses hollodotme/fast-cgi-client
trait ConnectsPhpFpmSocket {
protected function executeInFpm(string $code): string;
}

HTTP response caching headers and ETag support.

  • ETag generation and validation
  • Cache-Control header management
  • Vary header for cache key variation
  • 304 Not Modified responses

LaravelHttpCacheControlServiceProvider publishes configuration.

// Register globally or per-route
protected $middleware = [
\RightCapital\LaravelHttpCacheControl\SetCacheHeaders::class,
];
// Or per route
Route::get('/api/data', fn() => [...])
->middleware('setcacheheaders');
config/http-cache-control.php
return [
'vary' => [
'Accept',
'Authorization',
'Cookie',
],
'cache-control' => [
'public', // Cacheable by CDN
'max-age=3600', // Browser cache 1 hour
's-maxage=86400', // CDN cache 24 hours
'must-revalidate',
],
];
Cache-Control: public, max-age=3600, s-maxage=86400, must-revalidate
ETag: W/"e81fe3a0d3d3aa0a3f6d2b5c3d2e1a0b"
Vary: Accept, Authorization, Cookie

On subsequent requests with If-None-Match header matching the ETag:

HTTP/1.1 304 Not Modified
  • ETag Format: Weak ETag (W/) with base64-encoded MD5
  • Applies To: Response and JsonResponse only
  • Excludes: BinaryFileResponse, redirects, OPTIONS requests

Transparent file compression at the Flysystem adapter level.

  • GZIP compression (level 1-9)
  • Rule-based compression matching
  • Fallback to uncompressed files
  • Stream-based processing for large files
  • Metadata tracking for original size
use RightCapital\Flysystem\Compress\CompressAdapter;
use RightCapital\Flysystem\Compress\Compressor\Gzip;
$rules = [
[
'prefixes' => ['reports/', 'exports/'],
'suffixes' => ['.json', '.xml', '.csv'],
'fallback_to_origin_path' => true,
],
];
$compressed = new CompressAdapter(
adapter: $s3Adapter,
compressor: new Gzip(level: 6),
rules: $rules
);
reports/data.json.CD.gz
// Write - automatically compresses
$compressed->write('reports/data.json', json_encode($data));
// Read - automatically decompresses
$content = $compressed->read('reports/data.json');
// File size - returns original uncompressed size
$size = $compressed->fileSize('reports/data.json');
// List contents - hides .CD.gz files
foreach ($compressed->listContents('reports', false) as $file) {
echo $file->path(); // reports/data.json
}
// Compress all with fallback
CompressAdapter::COMPRESS_ALL_WITH_FALLBACK
// Or specific rules
[
'prefixes' => ['documents/'], // Match path prefixes
'suffixes' => ['.json'], // Match file extensions
'fallback_to_origin_path' => true, // Keep original if present
]

For large files, uses PHP stream filters to avoid memory exhaustion:

  • zlib.deflate for compression
  • GzipBigSize for RFC1952 compliance (>4GB files)
  • ByteCounter for tracking compressed size
  • Compressed files: {original}.CD.{ext} (e.g., data.json.CD.gz)
  • Hidden from directory listings
  • Automatic path translation on read/write

PackageCache LayerUse Case
laravel-file-storage-cacheApplicationCloud storage caching
laravel-command-cacheMulti-layerCache management CLI
laravel-http-cache-controlHTTPBrowser/CDN caching
flysystem-compress-adapterStorageFile compression
  1. File Storage Cache: Use when Redis unavailable but S3/cloud storage available
  2. Command Cache: Use in CI/CD for deployment cache cleanup
  3. HTTP Cache Control: Apply globally on API routes for automatic optimization
  4. Compress Adapter: Use for large file storage (logs, exports) to reduce costs