Alaa Amer Articles

We offer a comprehensive collection of essential educational articles in web development to turn your ideas into digital reality

Laravel Performance Optimization: Advanced Techniques & Monitoring

Laravel 2026-01-01 Alaa Amer

Laravel Performance Optimization: Advanced Techniques & Monitoring

Expert Guide by Alaa Amer – Professional Web Developer & Applications Designer

Laravel performance optimization is crucial for scalable applications. Master caching strategies, database optimization, queue management, and advanced monitoring techniques.

2️⃣ Advanced Caching Strategies

Multi-Layer Caching Implementation:

<?php
// app/Services/CacheService.php
namespace App\Services;

use Illuminate\Support\Facades\{Cache, Redis};
use Illuminate\Contracts\Cache\Repository;

class CacheService
{
    protected $cache;
    protected $redis;

    public function __construct(Repository $cache)
    {
        $this->cache = $cache;
        $this->redis = Redis::connection();
    }

    /**
     * Multi-layer caching with fallback
     */
    public function remember(string $key, $ttl, callable $callback, array $tags = [])
    {
        // Layer 1: Memory cache (fastest)
        static $memoryCache = [];

        if (isset($memoryCache[$key])) {
            return $memoryCache[$key];
        }

        // Layer 2: Application cache (Redis/Memcached)
        $value = $this->cache->tags($tags)->remember($key, $ttl, function () use ($callback, &$memoryCache, $key) {
            $result = $callback();
            $memoryCache[$key] = $result; // Store in memory for this request
            return $result;
        });

        return $value;
    }

    /**
     * Smart cache invalidation
     */
    public function invalidate(string $pattern): int
    {
        $keys = $this->redis->keys($pattern);

        if (empty($keys)) {
            return 0;
        }

        return $this->redis->del($keys);
    }

    /**
     * Cache warming for critical data
     */
    public function warm(array $keys): void
    {
        foreach ($keys as $key => $config) {
            if (!$this->cache->has($key)) {
                $value = call_user_func($config['callback']);
                $this->cache->put($key, $value, $config['ttl'] ?? 3600);
            }
        }
    }

    /**
     * Distributed cache lock
     */
    public function lock(string $key, int $timeout = 10): ?Lock
    {
        return $this->cache->lock($key, $timeout);
    }

    /**
     * Cache statistics
     */
    public function getStats(): array
    {
        $info = $this->redis->info('memory');

        return [
            'used_memory' => $info['used_memory_human'] ?? 'N/A',
            'hit_rate' => $this->getHitRate(),
            'key_count' => $this->redis->dbsize(),
            'expired_keys' => $info['expired_keys'] ?? 0,
            'evicted_keys' => $info['evicted_keys'] ?? 0
        ];
    }

    protected function getHitRate(): string
    {
        $info = $this->redis->info('stats');
        $hits = $info['keyspace_hits'] ?? 0;
        $misses = $info['keyspace_misses'] ?? 0;
        $total = $hits + $misses;

        if ($total === 0) {
            return '0%';
        }

        return round(($hits / $total) * 100, 2) . '%';
    }
}

// app/Services/PostCacheService.php - Domain-specific caching
namespace App\Services;

class PostCacheService
{
    protected $cacheService;

    public function __construct(CacheService $cacheService)
    {
        $this->cacheService = $cacheService;
    }

    public function getPopularPosts(int $limit = 10)
    {
        return $this->cacheService->remember(
            "posts.popular.{$limit}",
            3600, // 1 hour
            function () use ($limit) {
                return Post::published()
                    ->withCount(['likes', 'comments', 'views'])
                    ->orderByDesc('likes_count')
                    ->limit($limit)
                    ->get();
            },
            ['posts', 'popular']
        );
    }

    public function getPost(int $id)
    {
        return $this->cacheService->remember(
            "posts.{$id}",
            7200, // 2 hours
            function () use ($id) {
                return Post::with(['user', 'category', 'tags'])->find($id);
            },
            ['posts', "post.{$id}"]
        );
    }

    public function getCategoryPosts(int $categoryId, int $page = 1)
    {
        return $this->cacheService->remember(
            "posts.category.{$categoryId}.page.{$page}",
            1800, // 30 minutes
            function () use ($categoryId, $page) {
                return Post::where('category_id', $categoryId)
                    ->published()
                    ->with(['user', 'tags'])
                    ->paginate(15, ['*'], 'page', $page);
            },
            ['posts', "category.{$categoryId}"]
        );
    }

    public function invalidatePost(Post $post): void
    {
        $tags = [
            'posts',
            "post.{$post->id}",
            "category.{$post->category_id}",
            "user.{$post->user_id}.posts"
        ];

        Cache::tags($tags)->flush();

        // Also invalidate related caches
        if ($post->is_featured) {
            Cache::tags(['popular', 'featured'])->flush();
        }
    }

    public function warmCache(): void
    {
        $this->cacheService->warm([
            'posts.popular.10' => [
                'callback' => fn() => $this->getPopularPosts(10),
                'ttl' => 3600
            ],
            'posts.recent.20' => [
                'callback' => fn() => Post::published()->latest()->limit(20)->get(),
                'ttl' => 1800
            ],
            'categories.with_counts' => [
                'callback' => fn() => Category::withCount('posts')->get(),
                'ttl' => 7200
            ]
        ]);
    }
}

Response Caching Middleware:

<?php
// app/Http/Middleware/CacheResponse.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class CacheResponse
{
    public function handle(Request $request, Closure $next, int $ttl = 300)
    {
        // Only cache GET requests
        if ($request->method() !== 'GET') {
            return $next($request);
        }

        // Don't cache authenticated requests by default
        if (auth()->check() && !$request->has('public')) {
            return $next($request);
        }

        $cacheKey = $this->getCacheKey($request);

        // Try to get cached response
        $cachedResponse = Cache::get($cacheKey);

        if ($cachedResponse) {
            return response($cachedResponse['content'])
                ->withHeaders($cachedResponse['headers'])
                ->header('X-Cache-Status', 'HIT');
        }

        // Generate response
        $response = $next($request);

        // Only cache successful responses
        if ($response->getStatusCode() === 200) {
            $cacheData = [
                'content' => $response->getContent(),
                'headers' => [
                    'Content-Type' => $response->headers->get('Content-Type'),
                    'Cache-Control' => 'public, max-age=' . $ttl
                ]
            ];

            Cache::put($cacheKey, $cacheData, $ttl);
            $response->header('X-Cache-Status', 'MISS');
        }

        return $response;
    }

    protected function getCacheKey(Request $request): string
    {
        $url = $request->fullUrl();
        $acceptHeader = $request->header('Accept', 'text/html');

        return 'response_cache:' . md5($url . $acceptHeader);
    }
}

// Usage in routes
Route::middleware(['cache.response:3600'])->group(function () {
    Route::get('/blog', [BlogController::class, 'index']);
    Route::get('/blog/{post}', [BlogController::class, 'show']);
});

4️⃣ Queue & Job Optimization

High-Performance Queue Configuration:

<?php
// app/Jobs/OptimizedEmailJob.php
namespace App\Jobs;

use Illuminate\Bus\{Queueable, Batchable};
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\{InteractsWithQueue, SerializesModels, Middleware\WithoutOverlapping};

class OptimizedEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Batchable;

    public $timeout = 120;
    public $maxExceptions = 3;
    public $backoff = [10, 30, 60]; // Exponential backoff

    protected $userId;
    protected $emailData;

    public function __construct(int $userId, array $emailData)
    {
        $this->userId = $userId;
        $this->emailData = $emailData;

        // Optimize queue routing
        $this->onQueue('emails');
    }

    public function middleware(): array
    {
        return [
            // Prevent duplicate jobs
            new WithoutOverlapping($this->userId),

            // Rate limiting
            (new RateLimited('emails'))->allow(100)->everyMinute(),
        ];
    }

    public function handle(): void
    {
        $user = User::find($this->userId);

        if (!$user || !$user->email_notifications_enabled) {
            return;
        }

        try {
            Mail::to($user)->send(new UserNotification($this->emailData));

            // Update user activity
            $user->touch('last_email_sent_at');

        } catch (Exception $e) {
            // Log the error
            Log::error('Email job failed', [
                'user_id' => $this->userId,
                'error' => $e->getMessage(),
                'attempts' => $this->attempts()
            ]);

            // Release job for retry if attempts remaining
            if ($this->attempts() < $this->maxExceptions) {
                $this->release($this->backoff[$this->attempts() - 1] ?? 60);
            } else {
                $this->fail($e);
            }
        }
    }

    public function failed(Exception $exception): void
    {
        // Handle permanent failure
        Log::critical('Email job permanently failed', [
            'user_id' => $this->userId,
            'exception' => $exception->getMessage()
        ]);

        // Notify administrators
        NotificationFacade::route('slack', '#alerts')
            ->notify(new JobFailedNotification($this, $exception));
    }
}

// app/Console/Commands/OptimizeQueues.php
namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\{Queue, Redis};

class OptimizeQueues extends Command
{
    protected $signature = 'queue:optimize';
    protected $description = 'Optimize queue performance and clean up failed jobs';

    public function handle(): void
    {
        $this->info('Optimizing queue performance...');

        // Clean up old failed jobs
        $this->cleanupFailedJobs();

        // Balance queue workers
        $this->balanceWorkers();

        // Monitor queue health
        $this->monitorQueueHealth();

        $this->info('Queue optimization completed!');
    }

    protected function cleanupFailedJobs(): void
    {
        $olderThan = now()->subDays(7);

        $deleted = DB::table('failed_jobs')
            ->where('failed_at', '<', $olderThan)
            ->delete();

        $this->line("Cleaned up {$deleted} old failed jobs");
    }

    protected function balanceWorkers(): void
    {
        $queueSizes = [
            'default' => Queue::size('default'),
            'emails' => Queue::size('emails'),
            'high' => Queue::size('high'),
            'low' => Queue::size('low')
        ];

        $this->table(
            ['Queue', 'Size', 'Recommended Workers'],
            collect($queueSizes)->map(function ($size, $name) {
                $workers = $this->calculateOptimalWorkers($size);
                return [$name, $size, $workers];
            })->values()->toArray()
        );
    }

    protected function calculateOptimalWorkers(int $queueSize): int
    {
        if ($queueSize === 0) return 1;
        if ($queueSize <= 10) return 2;
        if ($queueSize <= 100) return 5;
        if ($queueSize <= 1000) return 10;
        return 20;
    }

    protected function monitorQueueHealth(): void
    {
        $redis = Redis::connection();
        $info = $redis->info('memory');

        $memoryUsage = $info['used_memory_human'] ?? 'Unknown';
        $this->line("Redis memory usage: {$memoryUsage}");

        // Check for stuck jobs
        $stuckJobs = DB::table('jobs')
            ->where('reserved_at', '<', now()->subMinutes(30))
            ->whereNotNull('reserved_at')
            ->count();

        if ($stuckJobs > 0) {
            $this->warn("Found {$stuckJobs} potentially stuck jobs");
        }
    }
}

Queue Monitoring Dashboard:

<?php
// app/Http/Controllers/Admin/QueueMonitorController.php
namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\{Queue, DB, Redis};

class QueueMonitorController extends Controller
{
    public function dashboard()
    {
        $stats = [
            'queue_sizes' => $this->getQueueSizes(),
            'failed_jobs' => $this->getFailedJobsStats(),
            'worker_status' => $this->getWorkerStatus(),
            'throughput' => $this->getThroughputStats(),
            'memory_usage' => $this->getMemoryUsage()
        ];

        return view('admin.queue-dashboard', compact('stats'));
    }

    protected function getQueueSizes(): array
    {
        return [
            'default' => Queue::size('default'),
            'high' => Queue::size('high'),
            'emails' => Queue::size('emails'),
            'low' => Queue::size('low')
        ];
    }

    protected function getFailedJobsStats(): array
    {
        return [
            'total' => DB::table('failed_jobs')->count(),
            'last_24h' => DB::table('failed_jobs')
                ->where('failed_at', '>=', now()->subDay())
                ->count(),
            'by_queue' => DB::table('failed_jobs')
                ->select('queue', DB::raw('COUNT(*) as count'))
                ->groupBy('queue')
                ->get()
                ->pluck('count', 'queue')
                ->toArray()
        ];
    }

    protected function getWorkerStatus(): array
    {
        // This would integrate with your process manager
        return [
            'active_workers' => 5, // Get from supervisor/systemd
            'idle_workers' => 2,
            'busy_workers' => 3
        ];
    }

    protected function getThroughputStats(): array
    {
        $hourly = [];
        for ($i = 23; $i >= 0; $i--) {
            $hour = now()->subHours($i)->format('Y-m-d H:00:00');
            $hourly[$hour] = DB::table('job_batches')
                ->where('finished_at', '>=', $hour)
                ->where('finished_at', '<', now()->subHours($i-1)->format('Y-m-d H:00:00'))
                ->sum('total_jobs') ?? 0;
        }

        return $hourly;
    }

    protected function getMemoryUsage(): array
    {
        $redis = Redis::connection();
        $info = $redis->info();

        return [
            'used_memory' => $info['used_memory_human'] ?? 'N/A',
            'peak_memory' => $info['used_memory_peak_human'] ?? 'N/A',
            'fragmentation_ratio' => $info['mem_fragmentation_ratio'] ?? 'N/A'
        ];
    }
}

Next Steps

Deploy your optimized Laravel application with Deployment & DevOps strategies for production environments.

📩 Need help with Laravel performance?

Laravel Performance Optimization Caching Database Optimization Scaling Monitoring Profiling
Article Category
Laravel

Laravel Performance Optimization: Advanced Techniques & Monitoring

Master Laravel performance optimization with caching, database optimization, queue management, profiling tools, and enterprise-level scaling strategies.

Laravel Performance Optimization: Advanced Techniques & Monitoring
01

Consultation & Communication

Direct communication via WhatsApp or phone to understand your project needs precisely.

02

Planning & Scheduling

Creating clear work plan with specific timeline for each project phase.

03

Development & Coding

Building projects with latest technologies ensuring high performance and security.

04

Testing & Delivery

Comprehensive testing and thorough review before final project delivery.

Alaa Amer
Alaa Amer

Professional web developer with over 10 years of experience in building innovative digital solutions.

Need This Service?

Contact me now for a free consultation and quote

WhatsApp Your satisfaction is our ultimate goal

What We Offer

  • Website Maintenance & Updates

    Keep your website secure updated optimized

  • API Integration

    Connect your systems with powerful APIs

  • Database Design & Optimization

    Faster queries cleaner structure fewer issues

  • Website Security Hardening

    Protect your site from cyber threats

  • Automation & Scripts

    Automate repetitive tasks and save time

Have Questions?

Call Us Now

00201014714795