Get in Touch
Laravel Performance Optimisation: From Slow to Sub-100ms Response Times
PHP Development February 6, 2026 4 min read

Laravel Performance Optimisation: From Slow to Sub-100ms Response Times

cp_nitinj
CodePulseDigital Team
Home โ€บ Blog โ€บ PHP Development

Laravel applications have a reputation for being slower than raw PHP or lighter frameworks, and for many applications this reputation is deserved โ€” not because Laravel itself is slow, but because the features and abstractions it provides make it easy to write inefficient code without realising it. The N+1 query problem, redundant configuration loading, unoptimised autoloading, and missing cache layers are the categories where performance is most commonly lost, and they are all fixable with targeted intervention.

Diagnosis First: Measure Before You Optimise

Performance optimisation without measurement is guesswork. Laravel Telescope (for local environments) and Laravel Debugbar provide request-level visibility into query count, query time, cache hit/miss rates, and memory usage. Identifying which routes are slow, how many queries they execute, and where execution time is concentrated is the prerequisite for any meaningful improvement. The instinct to add caching everywhere before understanding the bottleneck results in complex cache invalidation logic for code paths that were not the problem.

The N+1 Problem: The Most Common Laravel Performance Killer

The N+1 problem occurs when an application executes one query to retrieve a collection and then N additional queries (one per item in the collection) to retrieve associated data. A page displaying 50 orders, each showing the customer name, executes 51 queries: one for the orders, and one per order to retrieve the customer. With Eloquent relationships, this happens silently when relationships are accessed without eager loading.

The fix is eager loading: $orders = Order::with(‘customer’, ‘items’)->get(). This executes three queries regardless of collection size: one for orders, one for all associated customers, one for all associated items. Telescope or Debugbar will show duplicate queries with varying IDs, which is the reliable indicator of an N+1 issue. Eliminating N+1 issues is typically the highest-impact optimisation available for Eloquent-based applications.

Caching: Configuration, Routes, and Data

Laravel provides three caching layers that are frequently left unconfigured. php artisan config:cache merges all configuration files into a single cached file, eliminating the filesystem reads on every request that configuration loading normally requires. php artisan route:cache compiles all routes into a single cached file, which Laravel uses directly without parsing route definition files on each request. Both should be part of any production deployment pipeline.

Application-level data caching โ€” using Cache::remember() to store the results of expensive queries โ€” requires more thought but delivers the largest performance improvements for read-heavy endpoints. Cache invalidation strategy (time-based, event-based, or tag-based) needs to be designed carefully to avoid stale data, but the performance impact of caching a query that runs 1000 times per minute with static results is substantial.

Queue Heavy Work Outside the Request Cycle

Sending emails, generating PDFs, processing uploaded files, making third-party API calls โ€” any operation that is slow, unreliable, or not required for the immediate response should be dispatched as a queued job. Laravel’s queue system with Redis driver handles this elegantly: dispatch a job from a controller action, return a response immediately, and let the queue worker process the job asynchronously. Response times for endpoints that previously waited for email delivery or file processing become milliseconds instead of seconds.

Database Indexing: Often the Last Thing Checked

Missing indexes on columns used in WHERE clauses, JOIN conditions, and ORDER BY expressions are a common source of slow queries that become critical as table sizes grow. A query that runs in 20ms on a table with 1,000 rows may take 20 seconds on the same table with 10 million rows if the relevant column lacks an index. Running EXPLAIN on slow queries identified by Telescope reveals whether indexes are being used. Adding the appropriate index is typically a one-line migration and can reduce query time by orders of magnitude.

Share X / Twitter LinkedIn
PHP Development
โ† Back to all articles