Laravel Precision Monitoring: Break Down and Analyze Each Step of Your Code
๐ Why Performance Monitoring is Essential in Laravel Projects
In todayโs digital landscape, web application performance isn't just a luxuryโit's a necessity. A slow Laravel app can damage user satisfaction, harm your SEO rankings, and reduce conversions.
If you're serious about optimizing your Laravel app, you need more than just guesswork. You need actionable metrics.
In this guide, you'll learn how to implement a robust performance monitoring system in Laravel that:
- โ Tracks total request time
- โ Supports custom timing breakpoints to measure specific operations
- โ Stores performance logs as structured JSON
- โ Can be easily disabled in production
- โ Integrates smoothly with your middleware, controllers, and jobs
Whether you're troubleshooting slow APIs or preparing for high-traffic production, this tool will give you visibility where you need it most.
โ๏ธ Step 1: Configure a Dedicated JSON Log Channel in Laravel
To store performance metrics separately from your default logs, add a new channel to config/logging.php
:
'performance_monitor' => [
'driver' => 'single',
'path' => storage_path('logs/performance_monitor.json'),
'formatter' => \Monolog\Formatter\JsonFormatter::class,
'formatter_with' => [
'include_stacktraces' => true,
],
'level' => 'info',
],
This makes it easy to analyze logs using tools like Kibana, Datadog, Grafana, or custom dashboards.
๐ก๏ธ Step 2: Create the Performance Monitoring Middleware
In app/Http/Middleware/PerformanceMonitorMiddleware.php
:
This middleware tracks the total request time and allows developers to insert custom breakpoints.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Log;
class PerformanceMonitorMiddleware
{
protected $startTime;
protected $breakpoints = [];
protected $enabled;
public function __construct()
{
$this->enabled = config('app.performance_monitor_enabled');
}
public function handle($request, Closure $next)
{
if (!$this->enabled) {
return $next($request);
}
$this->startTime = defined('LARAVEL_START') ? LARAVEL_START : microtime(true);
// Register shutdown function as backup
register_shutdown_function(function () {
$this->logBreakpoints();
});
// Make the monitor available throughout the app
$request->attributes->set('performance_monitor', $this);
return $next($request);
}
public function terminate($request, $response)
{
if (!$this->enabled) {
return;
}
$this->logBreakpoints();
}
public function addBreakpoint($id)
{
if (!$this->enabled) {
return;
}
$this->breakpoints[$id] = microtime(true);
}
protected function logBreakpoints()
{
if (empty($this->breakpoints)) {
return;
}
$logEntry = [
'timestamp' => now()->toISOString(),
'url' => request()->fullUrl(),
'method' => request()->method(),
'breakpoints' => [],
'total_time' => round((microtime(true) - $this->startTime) * 1000, 2) . 'ms',
];
$previousTime = $this->startTime;
foreach ($this->breakpoints as $id => $time) {
$elapsed = $time - $previousTime;
$totalElapsed = $time - $this->startTime;
$logEntry['breakpoints'][] = [
'id' => $id,
'elapsed_since_previous_ms' => round($elapsed * 1000, 2),
'total_elapsed_ms' => round($totalElapsed * 1000, 2),
'timestamp' => $time,
];
$previousTime = $time;
}
Log::channel('performance_monitor')->info('Performance metrics', $logEntry);
}
}
Middleware Highlights:
- โ
Accurate time tracking with
LARAVEL_START
- ๐ Custom breakpoints for detailed insights
- ๐ Works even if
terminate()
fails (shutdown fallback) - ๐ Logs full URL and HTTP method
๐งฉ Step 3: Register the Middleware in Your App
Either apply it globally or only on routes that matter:
$middleware->appendToGroup('web', [
\App\Http\Middleware\PerformanceMonitorMiddleware::class,
]);
For APIs, consider adding it to the api
group or specific controllers.
๐ง Step 4: Add a Global Service for Easy Breakpoint Access
Update AppServiceProvider
to bind a simple performance monitor service:
$this->app->singleton('performance_monitor', function () {
return new class {
public function addBreakpoint($id)
{
if ($monitor = request()->attributes->get('performance_monitor')) {
$monitor->addBreakpoint($id);
}
}
};
});
You can now use app('performance_monitor')->addBreakpoint('some_point');
anywhere in your app!
๐ Step 5: Enable or Disable Performance Tracking via .env
In config/app.php
, add:
'performance_monitor_enabled' => env('PERFORMANCE_MONITOR_ENABLED', true),
Then toggle it in .env
:
PERFORMANCE_MONITOR_ENABLED=false
This keeps your production logs clean when needed.
๐งช Example in a Controller
public function getUserData($id)
{
app('performance_monitor')->addBreakpoint('start');
$user = User::with('posts')->findOrFail($id);
app('performance_monitor')->addBreakpoint('after_query');
$processedData = $this->processUserData($user);
app('performance_monitor')->addBreakpoint('after_processing');
return response()->json($processedData);
}
๐ Sample Output: JSON Performance Log
{
"timestamp": "2025-05-08T12:00:00Z",
"url": "https://example.com/api/users/123",
"method": "GET",
"breakpoints": [
{ "id": "after_query", "elapsed_since_previous_ms": 45.21 },
{ "id": "after_processing", "elapsed_since_previous_ms": 30.15 }
],
"total_time": "75.36ms"
}
๐ง How to Analyze Performance Logs
- ๐ Visualize in Kibana for real-time dashboards
- โฐ Set up alerts for requests over 500ms
- ๐ Spot bottlenecks by comparing breakpoints
- ๐ Track improvements after optimization changes
โ Conclusion: Take Control of Laravel Performance
By following this tutorial, youโve added a lightweight, configurable, and insightful performance monitoring tool to your Laravel stack.
๐ฏ Benefits Recap:
- Gain visibility into request timing
- Measure code-level bottlenecks
- Keep logs structured and searchable
- Turn off monitoring anytime with
.env
๐ฎ Whatโs Next?
Enhance this system with:
- ๐ฆ Memory usage tracking
- ๐ Frontend performance correlation (via request ID)
- ๐ฅ Email/Slack alerts for slow requests