[ GUIDE ]

Debugging Laravel performance in production

A structured, repeatable workflow — from "the /checkout page is slow" to "the third-party fraud API p95 grew 8x." Trace-based, not guess-based.

QUICK ANSWER

How do I debug Laravel performance issues in production?

Use a trace-based workflow: find the slow route via APM p95 dashboards, drill into the slowest individual requests to see their component spans, identify the dominant span (usually a DB query or external HTTP call), reproduce locally with matching seed data, fix, verify in production. Avoid live debugging — your APM traces should contain enough context to diagnose without it. Laravel's nightwatch package records full per-request traces that NightOwl surfaces as click-through debugging.

Updated · 2026-04-13

The debugging workflow

01

Identify the symptom precisely

Which route? Which user segment? Which time window? 'The app is slow' is not actionable. 'POST /api/checkout p95 went from 400ms to 2.1s after 14:00 UTC on 2026-04-12' is.

02

Pull a trace for a slow instance

Find the slowest requests in the affected time window. Open a trace — APMs break the request into spans (DB queries, cache calls, HTTP, view rendering). The largest span is your starting point.

03

Classify the bottleneck layer

App code, DB, cache, external HTTP, or view rendering. ~80% of the time it's DB. Of DB issues, ~70% are N+1 queries. Narrow fast.

04

Reproduce locally with realistic data

Seed staging or local from anonymized production. Hit the same endpoint with similar payloads. Reproduce with Telescope or Clockwork for call-level detail Xdebug can add if needed.

05

Fix and deploy behind a flag

Use a feature flag so you can roll back instantly. Verify fix reduces p95 in production before removing the flag.

06

Document the root cause

A one-paragraph post-mortem per incident beats repeating the same discovery six months later. Include the trace URL, the fix, and the monitoring gap that let it land.

Tools by situation

Situation Tool Why
Production trace neededNightOwl / Nightwatch CloudAlways-on per-request traces
Local call-level profilingXdebug + KCacheGrindFunction-level timing depth
Local request inspectionTelescope / ClockworkPer-request query + event detail
DB query plan analysisEXPLAIN ANALYZEPlanner decisions that matter
Production-safe profilingSPX (PHP profiler)Low-overhead, sampled
Memory debuggingmemory_get_peak_usage in middlewareCheap and precise

What you should never do in production

  • Run Xdebug — 10x+ overhead on every request
  • Drop into tinker on a live server — one typo and you've mass-updated a table
  • Add dd() or dump() calls — they return raw HTML from every request
  • Enable query logging globally without sampling — will bloat your DB or log store in minutes
  • Run EXPLAIN ANALYZE on write queries — it actually executes them

THE EASY WAY

Traces so you never debug in prod

NightOwl records every request with full per-span context — DB queries with durations, cache hits/misses, outgoing HTTP calls. Click a slow request and see exactly which span owned the latency. No more guessing or reproducing blind.

bash
composer require nightowl/agent
php artisan nightowl:install

From $5/month flat. Data in your PostgreSQL.

Frequently asked questions

How do I debug Laravel performance issues in production without breaking things?

The safe sequence: (1) reproduce locally with seeded data that matches production shape, (2) use Laravel Telescope or Clockwork in staging to identify the bottleneck layer (app code, DB, cache, external HTTP), (3) add targeted instrumentation or APM visibility in production, (4) verify the fix lands before removing the instrumentation. Avoid running debuggers or tinker on production — use APM-level traces instead.

What's the fastest way to find why a Laravel endpoint is slow?

Get a per-request trace of the slow endpoint. APMs give you this: the request is broken into spans (DB queries, cache calls, external HTTP, view rendering) with durations. The largest span is the bottleneck. In 80%+ of cases it's DB queries — usually an N+1 or a missing index. For the other 20%, look at external HTTP first, then view rendering, then cache misses.

Can I use Xdebug for Laravel performance debugging?

For call-level profiling yes — Xdebug's profile output loaded into KCacheGrind or Qcachegrind shows where time is spent at the PHP function level. Don't run Xdebug in production — its overhead is too high. Use it locally with a reproduction of the slow production case. For production-safe profiling, use an APM or PHP's lightweight SPX profiler.

How do I tell if a Laravel performance regression was caused by my deploy?

Compare p95 latency per route before and after the deploy timestamp. If p95 for specific routes jumped immediately after deploy, the deploy is the cause. Look at the diff since the last deploy for changes to the affected controllers, Eloquent queries, or middleware. Roll back if the regression is severe while you investigate.

Should I use EXPLAIN ANALYZE on slow production queries?

Yes, but carefully. EXPLAIN ANALYZE actually runs the query — safe for SELECTs, dangerous for anything that mutates state. For write queries, use EXPLAIN (without ANALYZE) which returns the plan without executing. Compare plans between expected (from local reproduction) and actual (production) — differences in index usage or join order often explain slowness.

How do I debug Laravel memory issues in production?

Log peak memory per request with request context (route, user). Aggregate by route to find outliers. For individual problematic requests, reproduce locally with the same input and use PHP's memory_get_usage at key points to narrow down where the spike happens. See our memory-usage guide.

What causes sudden Laravel latency spikes under normal load?

Common causes: (1) a cache that warmed up during deploy is now cold after eviction, (2) database statistics gone stale causing the query planner to pick a bad plan (run ANALYZE), (3) a cron job running in-process that wasn't there before, (4) autoscaling bringing up new workers without connection pool capacity, (5) a third-party API you depend on went slow. APM per-request traces distinguish these fast.

How do I avoid debugging in prod?

Three practices: (1) seed staging from anonymized production data so you can reproduce realistic bottlenecks, (2) invest in an APM that records enough context to debug from traces alone, (3) set per-route latency SLOs and alert on regressions — you catch issues before they need live debugging. Debugging in prod is what you do when the other three fail.

PRICING

Flat pricing. No event caps. No per-seat fees.

14-day free trial, no credit card. Your PostgreSQL, your data.

HOBBY

$5 /month

1 app · 14 days lookback · all Laravel events

TEAM

$15 /month

Up to 3 connected apps · unlimited environments · all Laravel events

AGENCY

$69 /month

Unlimited apps · unlimited agent instances · same flat rate at any traffic

Related