3 min read

Why Your Laravel App Is Slow (And How to Actually Fix It)

If your Laravel app feels slow, chances are you’re fixing the wrong things. Here are the real reasons Laravel apps drag — and what actually makes them fast again.
Why Your Laravel App Is Slow (And How to Actually Fix It)

At some point, every Laravel app hits that moment.

Pages feel sticky.
API responses take just a little too long.
You open Chrome DevTools and watch requests… linger.

Your first instinct is usually the wrong one.

You don’t need Redis everywhere.
You don’t need to rewrite things in Go.
You probably don’t even need to “optimize” yet.

Most slow Laravel apps aren’t slow because Laravel is slow.
They’re slow because of a handful of common mistakes that quietly pile up over time.

Let’s walk through the real reasons Laravel apps drag, and what actually fixes them.


1. The Silent Killer: N+1 Queries

If your app feels fine locally but crawls in production, this is often the culprit.

The symptom

  • One page loads dozens or hundreds of SQL queries
  • Database time dominates your request timeline
  • Everything gets worse as data grows

The cause

You load relationships lazily without realizing it.

$posts = Post::all();

foreach ($posts as $post) {
    echo $post->author->name;
}

That looks harmless.
It isn’t.

Laravel runs:

  • 1 query for posts
  • 1 query per author

That’s N+1 queries.

The fix

Use eager loading. Always.

$posts = Post::with('author')->get();

This single change can drop page load times from seconds to milliseconds.

Rule of thumb
If you loop and touch a relationship inside the loop, eager load it.


2. You’re Doing Work That Doesn’t Belong in a Request

HTTP requests should be fast and boring.

If your controller:

  • Sends emails
  • Generates PDFs
  • Processes images
  • Calls external APIs
  • Syncs data

…you’re slowing every user down.

The fix

Queues.

Laravel queues exist to move slow work out of the request lifecycle.

SendWelcomeEmail::dispatch($user);

Instead of:

Mail::to($user)->send(new WelcomeEmail());

Now your response returns immediately, and the heavy lifting happens in the background.

Bonus
Queues also make your app more reliable.
If something fails, it retries. Requests don’t.


3. You’re Hitting the Database Way Too Often

Databases are fast.
They’re just not free.

If you:

  • Load the same settings on every request
  • Recalculate counts constantly
  • Query reference data that barely changes

You’re wasting time.

The fix

Cache things that don’t change often.

$settings = Cache::remember('settings', 3600, function () {
    return Settings::first();
});

Caching isn’t about guessing.
It’s about recognizing repeat work and stopping it.

Good caching candidates

  • App configuration
  • Feature flags
  • Permissions
  • Dashboard aggregates
  • Expensive API responses

4. You Forgot to Turn On the Free Speed Boosts

Laravel ships with performance features people forget to enable.

In production, you should be running:

php artisan config:cache
php artisan route:cache
php artisan view:cache

Without these:

  • Config files are parsed every request
  • Routes are rebuilt constantly
  • Blade templates compile on demand

These commands cost nothing and save real time.

Important
Never cache config or routes in local development unless you know why you’re doing it.


5. Your App Is “Fast” but Your Queries Aren’t

Sometimes Laravel isn’t the problem.
Your SQL is.

Watch for:

  • Missing indexes
  • Large WHERE IN clauses
  • Sorting huge datasets in PHP instead of SQL
  • Pulling entire tables when you only need counts

Tools that help

  • Laravel Debugbar
  • Telescope
  • Database slow query logs

If a query takes 300ms, caching won’t save you.
Fix the query.


6. Horizon Isn’t Optional Once You Use Queues Seriously

If you’re using Redis queues in production and not running Horizon, you’re flying blind.

Horizon gives you:

  • Queue throughput visibility
  • Failed job tracking
  • Worker scaling control
  • Real insight into background performance

Queues are infrastructure.
Horizon is the dashboard.


7. The Hard Truth: Most “Optimizations” Are Guesswork

The biggest mistake developers make is optimizing without measuring.

Before changing anything, ask:

  • Is this database time, PHP time, or network time?
  • Is the delay consistent or spiky?
  • Does it scale with data size?

Laravel gives you the tools.
Use them before reaching for “clever” fixes.


A Simple Performance Checklist

If your Laravel app feels slow, start here:

  • [ ] Check for N+1 queries
  • [ ] Move slow tasks to queues
  • [ ] Cache repeat work
  • [ ] Enable config, route, and view caching
  • [ ] Inspect slow SQL
  • [ ] Monitor queues with Horizon

Do these well, and most performance problems disappear.


Coming Next (This Will Be a Series)

Each of these topics deserves a deeper dive.
In future posts, we’ll break down:

  • Debugging N+1s like a pro
  • Designing cache layers that don’t lie
  • Queue architecture that scales cleanly
  • When Laravel is fast enough — and when it isn’t

Laravel isn’t slow.
Unexamined apps are.