Skip to content
Mehedi Hasan Sagor

// blog

Laravel Performance Tuning: Practical Steps to Speed Up Production Apps

Mehedi Hasan Sagor Oct 23, 2026 5 min read
Laravel Performance Tuning: Practical Steps to Speed Up Production Apps

When a startup moves from a prototype to a paying customer base, the first thing that starts to bite is performance. Laravel gives you a lot of conveniences out of the box, but those conveniences can also hide costly patterns. This post walks through concrete, production‑ready tweaks you can apply today—no fancy hardware, just Laravel‑native tools and disciplined engineering.

1. Cache Everything You Can (and Should)

Laravel ships with several cache drivers (file, Redis, Memcached). In production you almost always want Redis because it is in‑memory, supports TTLs, and works across multiple web‑servers.

// config/cache.php
'default' => env('CACHE_DRIVER', 'redis'),

'stores' => [
    'redis' => [
        'driver' => 'redis',
        'connection' => 'cache',
    ],
],

Route & Config Caching

Both are single‑command optimizations that reduce the amount of work Laravel does on each request.

php artisan config:cache   # compiles all config files into a single PHP file
php artisan route:cache    # caches the route collection (only works with static routes)

When to avoid route cache? If you rely on runtime route registration (e.g., routes loaded from a database) you must keep the cache disabled or rebuild it during deployment.

View Caching

Blade templates are compiled to plain PHP the first time they are rendered. In production you can pre‑compile them:

php artisan view:cache

If you use a CDN for static assets, remember to set the Cache-Control header to a reasonable max‑age (e.g., 1 week) and version assets with a hash in the filename.

2. Optimize Database Access

Eager Loading vs Lazy Loading

The classic N+1 query problem is the biggest performance killer in Laravel. Use eager loading on relationships you know you’ll need.

// Bad: triggers a query per post
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // lazy loads author
}

// Good: loads authors in a single query
$posts = Post::with('author')->get();
foreach ($posts as $post) {
    echo $post->author->name;
}

Query Caching

For read‑heavy endpoints you can cache the result set.

$users = Cache::remember('active-users', now()->addMinutes(5), function () {
    return User::where('active', true)->get();
});

Make sure the cache key includes any parameters that affect the query (e.g., pagination, filters).

Indexes

Never ship a migration without thinking about indexes. A missing index can turn a SELECT that should be microseconds into a full table scan.

Schema::table('orders', function (Blueprint $table) {
    $table->index(['user_id', 'status']); // composite index for common filter
});

Use EXPLAIN in MySQL or EXPLAIN ANALYZE in PostgreSQL to verify that the optimizer uses your index.

3. Queue Workers & Job Batching

Synchronous processing is the simplest, but it ties up PHP workers and inflates request latency. Move anything that can be done asynchronously to a queue.

// Dispatch a job
ProcessInvoice::dispatch($invoiceId);

Supervisor Configuration

A typical Supervisor config for Laravel queues (Redis driver) looks like this:

[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work redis --sleep=3 --tries=3 --timeout=60
autostart=true
autorestart=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/laravel-queue.log

Four workers give you parallelism without overwhelming the server. Adjust numprocs based on CPU cores and the average job duration.

Job Batching for Bulk Operations

Laravel 8 introduced job batching, which is perfect for bulk imports.

Bus::batch([
    new ImportUser($row1),
    new ImportUser($row2),
    // …
])->dispatch();

Batches give you a single place to hook into then, catch, and finally callbacks, making error handling deterministic.

4. Serve Faster with Laravel Octane

Octane replaces the traditional PHP‑FPM request lifecycle with a long‑running worker (Swoole or RoadRunner). The biggest win is eliminating the bootstrap cost on every request.

composer require laravel/octane
php artisan octane:install --server=swoole
php artisan octane:start --workers=8

Things to Watch

  • Stateless services: Avoid storing request‑specific state on the container (e.g., singletons that hold the current user).
  • Cache warm‑up: Warm the route, config, and view caches before starting Octane to avoid a cold‑start spike.
  • Graceful reloads: Use php artisan octane:reload during deployments so existing workers finish their jobs before being replaced.

Octane can cut average request time by 30‑50 % for CPU‑bound Laravel apps, but it adds operational complexity. If you already have a robust CI/CD pipeline and can afford a small learning curve, the performance payoff is worth it.

5. Monitoring & Alerting – Close the Loop

Performance tuning is an ongoing process. Without observability you’ll never know if a change regressed latency.

Metrics

  • Response time: Use Laravel Telescope or an external APM (e.g., New Relic, Datadog) to capture request duration.
  • Queue lag: php artisan queue:work --daemon prints the number of pending jobs; expose this via a Prometheus metric.
  • Cache hit ratio: Redis INFO stats gives keyspace_hits vs keyspace_misses.

Alerts

Set thresholds that matter for your business—e.g., 95th‑percentile request time > 300 ms, queue lag > 500 jobs, cache hit ratio < 85 %. Hook alerts to Slack or PagerDuty so the on‑call engineer can act quickly.

Takeaway

Performance is not a one‑off checklist; it’s a habit of constantly questioning where latency hides. Start with the low‑hanging fruit—cache, eager loading, and queue workers. Then evaluate whether Octane or a more aggressive caching strategy (e.g., full‑page caching with Varnish) makes sense for your traffic pattern. Finally, instrument everything so you can prove that each change moves the needle in the right direction.

By applying these practical steps you’ll keep your Laravel application responsive, reduce server costs, and give your users the smooth experience they expect from a modern SaaS product.

  • Laravel
  • Php
  • Performance
  • Ops